/* 1KSMP Season 4 — Fissure. A coming-soon screen.
   Ink on washi: one colour besides the ink, the vermilion of a seal, and the
   empty paper doing as much work as the strokes. Nothing is centred for the
   sake of it — a hanging scroll is composed off-axis. */
:root {
  --washi:  #EFE9DC;
  --washi2: #E7DFCE;
  --sumi:   #17130F;
  --sumi2:  #453C33;
  --sumi3:  #736657;
  --sumi4:  #A1937F;
  --shu:    #B33A2B;
  --brush: "Zhi Mang Xing", "Shippori Mincho", cursive;
  --body: "Zen Kaku Gothic New", ui-sans-serif, system-ui, sans-serif;
}

* { box-sizing: border-box; }
a { color: inherit; }
html, body { margin: 0; min-height: 100%; }
body {
  background: var(--washi);
  color: var(--sumi);
  font: 400 clamp(1rem, 0.95rem + 0.2vw, 1.08rem)/1.75 var(--body);
  overflow-x: hidden;
}

/* Paper: fibre and an uneven tone. Fixed, so the sheet stays still.
 *
 *  It reaches past the top and bottom of the viewport by exactly the safe-area
 *  insets. The page is viewport-fit=cover, so on a phone it runs under the
 *  status bar and the toolbar — but a fixed layer at inset:0 stops at the
 *  viewport edge, leaving those two strips with the flat background colour and
 *  none of the texture over it. Against a textured sheet that reads as two
 *  pale bars. The insets resolve to zero everywhere that has none. */
.paper {
  position: fixed;
  top: calc(-15vh - env(safe-area-inset-top, 0px));
  bottom: calc(-15vh - env(safe-area-inset-bottom, 0px));
  left: 0;
  right: 0;
  pointer-events: none; z-index: 3;
  background:
    radial-gradient(120% 80% at 15% 0%, color-mix(in srgb, #FFF9EC 62%, transparent), transparent 58%),
    radial-gradient(100% 70% at 85% 100%, color-mix(in srgb, #DCD2BD 50%, transparent), transparent 62%); }
.paper svg { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0.3; mix-blend-mode: multiply; }

/* ---------- the scene ---------- */
/* lvh, not dvh. iOS only retracts the URL bar once the page actually scrolls,
   and dvh shrinks the scene to match the CURRENT chrome, so the page can never
   grow tall enough to trigger that retraction and the bar never leaves. lvh is
   the height with the chrome already gone, which makes the page a little taller
   than the visible area, which is exactly what lets Safari collapse it. */
.scene { position: relative; min-height: 100vh; min-height: 100lvh; display: flex; flex-direction: column; }
/* And the painting itself runs into the insets, so the mist and the hills do
   not stop in a straight line at the toolbar. */
.ink { margin-bottom: calc(-1 * env(safe-area-inset-bottom, 0px)); }
.ink { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.ink > * { position: absolute; will-change: transform; }
/* Bamboo and grass pivot at the root, the plum from the branch it hangs off. */
.bamboo, .tuft, .tuft2 { transform-origin: 50% 100%; }
.plum { transform-origin: 88% 12%; }
.ink svg { display: block; width: 100%; height: auto; }

.far   { left: -6%; right: -6%; bottom: 0;    width: 112%; }
.mid   { left: -4%; right: -4%; bottom: 4%;   width: 108%; opacity: 0.9; }
.bamboo{ left: 1%;  bottom: -2%; width: clamp(150px, 17vw, 280px); }
.plum  { right: -2%; top: -4%;  width: clamp(230px, 32vw, 520px); }
.tuft  { right: 6%; bottom: -1%; width: clamp(110px, 13vw, 200px); filter: blur(1.4px); opacity: 0.62; }
.tuft2 { left: 21%; bottom: -2%; width: clamp(90px, 11vw, 165px); filter: blur(2px); opacity: 0.5; }
@media (pointer: coarse) { .tuft, .tuft2 { filter: none; } }
@media (max-width: 620px) { .tuft2 { display: none; } .plum { width: 62vw; right: -12%; } }

.mist { position: absolute; left: 0; right: 0; bottom: 12%; height: 34vh; pointer-events: none;
  background: linear-gradient(to bottom, transparent, color-mix(in srgb, var(--washi) 82%, transparent) 55%, transparent); }

/* ---------- content ---------- */
.shell { width: min(1120px, 100% - 2.6rem); margin-inline: auto; position: relative; z-index: 2; }
.top { padding: 1.1rem 0; display: flex; align-items: center; gap: 1rem; }
.mark { display: flex; align-items: center; gap: 0.7rem; text-decoration: none; }
/* The brush mark itself, not the word. Sized by height so the blade keeps its
   proportions whatever the header does. */
.mark img { height: clamp(2.4rem, 4.4vw, 3.4rem); width: auto; display: block; }
.mark b { font-family: var(--brush); font-weight: 400; font-size: 1.6rem; letter-spacing: 0.06em; }
.mark i { font-style: normal; color: var(--shu); font-family: var(--brush); font-size: 1.3rem; }
.top a.d { margin-left: auto; font: 500 0.85rem/1 var(--body); letter-spacing: 0.1em; color: var(--sumi3); text-decoration: none; }
.top a.d:hover { color: var(--sumi); }

.mid-row { flex: 1; display: grid; grid-template-columns: auto 1fr; gap: clamp(1.2rem, 4vw, 3rem);
  align-items: center; padding: clamp(0.4rem, 1.6vh, 1.4rem) 0; }
@media (max-width: 720px) { .mid-row { grid-template-columns: 1fr; } .tate-side { display: none; } }

.tate-side { writing-mode: vertical-rl; text-orientation: upright; font-family: var(--brush);
  font-size: clamp(1.6rem, 3.6vw, 2.6rem); color: var(--sumi2); letter-spacing: 0.3em;
  height: clamp(13rem, 30vw, 21rem); }
.tate-side small { font-size: 0.45em; letter-spacing: 0.42em; color: var(--sumi4); }

.kicker { display: flex; align-items: center; gap: 0.8rem; margin-bottom: 0.6rem;
  font: 500 0.78rem/1 var(--body); letter-spacing: 0.34em; text-transform: uppercase; color: var(--sumi4); }
.kicker::before { content: ""; width: 42px; height: 1px; background: var(--sumi4); }

.wordmark { font-family: var(--brush); font-weight: 400; margin: 0;
  font-size: clamp(4.6rem, 17vw, 13rem); line-height: 0.86; letter-spacing: 0.01em; }
/* Each glyph moves on its own, so the word answers the cursor rather than
   sliding about as one block. */
.wordmark .ch { display: inline-block; will-change: transform; transition: color 0.35s ease; }
.wordmark:hover .ch { color: var(--shu); }
.wordmark .ch:hover { color: var(--shu); }
.stroke-wrap { display: block; margin: -3.5vw 0 0 -1vw; width: min(100%, 640px); }
.tagline { max-width: 30ch; margin: 0.9rem 0 0; font-size: clamp(1.05rem, 1rem + 0.5vw, 1.34rem);
  line-height: 1.6; color: var(--sumi2); }

.soon { display: inline-flex; align-items: center; gap: 0.8rem; margin-top: 1.2rem;
  font-family: var(--brush); font-size: clamp(1.7rem, 4.4vw, 2.6rem); color: var(--shu); }
.seal { display: inline-grid; place-items: center; width: 2.9rem; height: 2.9rem; border-radius: 3px;
  background: var(--shu); color: var(--washi); font-family: var(--brush); font-size: 1.4rem; line-height: 1;
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--washi) 28%, transparent); transform: rotate(-4deg); flex: none; }

.foot { padding: 0.9rem 0 1.6rem; position: relative; }
/* No panel under the links. A rectangle of paler paper read as a cut-out
   pasted over the painting, which is the one thing a scroll must not look
   like. The bamboo still grows up through this corner, so legibility is bought
   with a halo on the glyphs themselves — the paper shows through between the
   letters instead of behind the whole block. */
/* Deliberately not called "social" or "socials".
 *
 *  The filter lists behind Safari's content blockers — on by default on every
 *  iPhone — carry blanket cosmetic rules that hide those two class names
 *  outright. They are written to kill share widgets and do not stop to ask
 *  whether a given row is one. The markup below is a plain list of links to
 *  our own accounts, and it was being erased on the majority of phones for the
 *  crime of its class attribute. The links carry no class of their own for the
 *  same reason. */
.elsewhere { display: flex; flex-wrap: wrap; gap: 0.4rem 1.6rem; align-items: baseline; }
.elsewhere a { text-decoration: none; display: inline-flex; align-items: baseline; gap: 0.5rem;
  padding: 0.35rem 0; transition: color 0.18s; color: var(--sumi2); }
.elsewhere a b { font-family: var(--brush); font-weight: 400; font-size: 1.25rem; }
.elsewhere a span { color: var(--sumi4); font: 400 0.78rem/1 var(--body); }
.elsewhere a b, .elsewhere a span { text-shadow: 0 0 6px var(--washi), 0 0 12px var(--washi); }
.elsewhere a:hover { color: var(--shu); }
.foot-rule { height: 1px; background: color-mix(in srgb, var(--sumi) 14%, transparent); margin-bottom: 0.8rem; }
/* A phone is not a narrow desktop.
 *
 *  Measured at 375x812 the old layout left a hundred and eight pixels of dead
 *  air above the kicker, the same again below the seal, and gave the links a
 *  two-column block two hundred and thirty-nine pixels tall — twenty-nine per
 *  cent of the screen spent on six links. Everything below buys that space back
 *  and gives it to the painting. */
@media (max-width: 620px) {
  .top { padding: 0.7rem 0; }

  /* Sit the type near the top of its own space rather than floating in the
     middle of a stretched row. */
  .mid-row { align-items: start; padding: 2.6rem 0 0; }

  /* Fill the width. On a phone the name is the picture. */
  .wordmark { font-size: clamp(4.4rem, 23vw, 7rem); }
  .stroke-wrap { margin-top: -5vw; width: 100%; }
  .tagline { margin-top: 0.7rem; font-size: 1.06rem; }

  .soon { margin-top: 0.9rem; font-size: clamp(1.6rem, 8vw, 2.2rem); gap: 0.6rem; }
  .seal { width: 2.4rem; height: 2.4rem; font-size: 1.15rem; }

  /* Three columns, name over handle, tighter leading: the same six links in
     roughly half the height. */
  /* The inset alone is the home indicator, about 34px. Safari's toolbar sits on
     top of that and is roughly three times taller, which is what was slicing the
     second row of links in half. The retractable chrome is exactly the gap
     between the large and small viewports, so ask for it directly. */
  .foot { padding: 0.5rem 0 calc(0.9rem + env(safe-area-inset-bottom, 0px) + (100lvh - 100svh)); }
  .foot-rule { margin-bottom: 0.55rem; }
  .elsewhere { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.35rem 0.5rem; }
  .elsewhere a { flex-direction: column; gap: 0; padding: 0.1rem 0; }
  .elsewhere a b { font-size: 1.02rem; line-height: 1.15; }
  .elsewhere a span { font-size: 0.66rem; line-height: 1.2; }

  .bamboo { width: clamp(110px, 26vw, 160px); opacity: 0.75; }
}

/* Short phones in landscape, and small screens generally: the painting still
   has to leave room for the words. */
@media (max-height: 700px) and (max-width: 900px) {
  .wordmark { font-size: clamp(3.4rem, 16vw, 5rem); }
  .tagline { font-size: 0.98rem; }
  .soon { font-size: 1.5rem; margin-top: 0.6rem; }
  .seal { width: 2rem; height: 2rem; font-size: 1rem; }
  .mist { height: 26vh; }
}

/* ---------- the brush moving ---------- */
@keyframes wipeL { from { clip-path: inset(-30% 100% -30% -30%); } to { clip-path: inset(-30%); } }
@keyframes wipeR { from { clip-path: inset(-30% -30% -30% 100%); } to { clip-path: inset(-30%); } }
@keyframes wipeT { from { clip-path: inset(-30% -30% 100% -30%); } to { clip-path: inset(-30%); } }
@keyframes wipeB { from { clip-path: inset(100% -30% -30% -30%); } to { clip-path: inset(-30%); } }
@keyframes ink   { from { opacity: 0; } to { opacity: 1; } }
@keyframes bloom { from { opacity: 0; transform: scale(0.5); } to { opacity: 1; transform: scale(1); } }
@keyframes rise  { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@keyframes drift {
  0%   { transform: translate3d(0,-12vh,0) rotate(0deg);                     opacity: 0; }
  8%   { opacity: var(--o, 0.7); }
  35%  { transform: translate3d(calc(var(--lean, 4vw) * 0.7), 30vh, 0) rotate(150deg); }
  70%  { transform: translate3d(calc(var(--lean, 4vw) * -0.5), 68vh, 0) rotate(320deg); }
  92%  { opacity: var(--o, 0.7); }
  100% { transform: translate3d(var(--lean, -4vw), 114vh, 0) rotate(470deg); opacity: 0; }
}

/* Strokes rest FINISHED; the reveal is the exception, held blank through its
   own delay by `backwards`. Never make the un-animated state invisible — a
   backgrounded tab freezes animations and would show blank paper. */
.wipe-l { animation: wipeL var(--dur,1.1s) cubic-bezier(.32,.72,.3,1) var(--delay,0s) backwards; }
.wipe-r { animation: wipeR var(--dur,1.1s) cubic-bezier(.32,.72,.3,1) var(--delay,0s) backwards; }
.wipe-t { animation: wipeT var(--dur,1.1s) cubic-bezier(.32,.72,.3,1) var(--delay,0s) backwards; }
.wipe-b { animation: wipeB var(--dur,1.1s) cubic-bezier(.32,.72,.3,1) var(--delay,0s) backwards; }
.pop  { animation: bloom 0.55s cubic-bezier(.3,1.3,.5,1) var(--delay,0s) backwards; transform-origin: var(--ox,50%) var(--oy,50%); }
.fade { animation: ink 0.45s ease var(--delay,0s) backwards; }
.up   { animation: rise 0.9s cubic-bezier(.2,.8,.3,1) var(--delay,0s) backwards; }
.petal { position: fixed; top: 0; z-index: 2; pointer-events: none; opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .wipe-l, .wipe-r, .wipe-t, .wipe-b, .pop, .fade, .up { animation: none; }
  .petal { display: none; }
  .wordmark .ch { transform: none !important; }
}
