/* ============================================================
   JIYŪ JUTSU — one design system for every page
   White, black type. Colour only where it is content: the fighter
   cards and the Dojo belts. The one dark band is the Dojo member
   map (.band--inverse); remove that class and it turns white.
   ============================================================ */

/* the wordmark's own letters (J I Y U Ū T S, Playfair Display 800), self-hosted and preloaded on index so the
   wordmark never swaps glyphs mid-rise. 1.8KB, subset by Google Fonts. Licence: fonts/OFL.txt (SIL OFL 1.1; the subset
   carries its own family name because "Playfair Display" is a reserved font name). Every other glyph falls to Playfair. */
@font-face{font-family:"JJ Wordmark";font-style:normal;font-weight:800;font-display:block;src:url(fonts/wordmark-800-2026-11b.woff2) format("woff2");unicode-range:U+49-4A,U+53-55,U+59,U+12A,U+16A,U+232,U+304}

:root{
  /* palette (brief 01) */
  --paper:#fff;--ink:#111;--muted:#707072;--faint:#8a8a8c;--hair:#e5e5e5;
  --card:#fff;--tile:#f5f5f5;--tile-ink:#111;
  --accent:#111;--accent-ink:#fff;--accent-soft:#cacacb;--accent-hover:#39393b;
  /* one photo grade (Direction C): lifestyle photos sit muted so the colour stays with the cards and belts;
     product photos get a lighter touch of the same grade and stay true colour */
  --grade:saturate(.6) contrast(1.05) brightness(1.02);--grade-product:saturate(.84) contrast(1.03);
  /* design-direction names */
  --bg:#fff;--surface:#f5f5f5;--surface-hover:#e5e5e5;--ink-muted:#707072;--ink-disabled:#9e9ea0;
  --line:#cacacb;--line-strong:#8a8a8c;
  --inverse-bg:#111;--inverse-ink:#fff;--inverse-muted:#9e9ea0;--inverse-hair:rgba(255,255,255,.16);
  --focus:#111;--scrim:rgba(17,17,17,.32);
  --shadow-drawer:-24px 0 48px rgba(17,17,17,.08);
  --shadow-card:0 24px 48px -16px rgba(17,17,17,.35);
  --map-land:rgba(17,17,17,.2);

  /* type */
  --font-head:"Inter Tight","Inter",system-ui,sans-serif;
  --sans:"Inter",system-ui,-apple-system,"Segoe UI",sans-serif;
  --serif:"JJ Wordmark","Playfair Display","Times New Roman",serif; /* the wordmark only */
  --jp:"Noto Serif JP",serif;
  --px:"Press Start 2P",monospace;
  --fs-wordmark:clamp(4rem,2.59rem + 6.01vw,8rem);
  --fs-display:clamp(3rem,1.59rem + 6.01vw,7rem);
  --fs-h2:clamp(2.125rem,1.29rem + 3.57vw,4.5rem);
  --fs-h3:clamp(1.375rem,1.155rem + .94vw,2rem);
  --fs-lead:clamp(1.0625rem,1rem + .28vw,1.25rem);

  /* layout */
  --container:1440px;--page-x:clamp(20px,4vw,48px);--gap:clamp(12px,1.2vw,16px);
  --section-y:clamp(3.5rem,2.2rem + 4vw,6rem);--shelf-y:clamp(3rem,1.8rem + 2.8vw,4.5rem);--nav-h:56px;

  /* motion */
  --ease-out:cubic-bezier(.16,1,.3,1);--ease-std:cubic-bezier(.4,0,.2,1);--ease-expr:cubic-bezier(.6,0,.1,1);
}
@media(min-width:960px){:root{--nav-h:64px}}

/* the one dark moment — every component inside reads these tokens */
.band--inverse{--paper:#111;--ink:#fff;--muted:#9e9ea0;--hair:rgba(255,255,255,.16);--accent:#fff;--accent-ink:#111;--accent-soft:rgba(255,255,255,.5);--focus:#fff;
  --accent-hover:#d9d9d9;--surface:#1c1c1c;--line:rgba(255,255,255,.32);--line-strong:rgba(255,255,255,.55);--faint:rgba(255,255,255,.55);--map-land:rgba(255,255,255,.22);
  background:var(--paper);color:var(--ink)}

*,*::before,*::after{box-sizing:border-box}
html,body{margin:0;padding:0;background:var(--paper);color:var(--ink)}
html{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;scroll-behavior:smooth;scroll-padding-top:var(--nav-h);-webkit-text-size-adjust:100%}
body{font-family:var(--sans);font-weight:400;line-height:1.5;overflow-x:hidden;text-wrap:pretty}
body{font-size:16px;padding-top:var(--nav-h)}
img{display:block;max-width:100%;height:auto}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}
::selection{background:var(--ink);color:var(--paper)}
:focus-visible{outline:2px solid var(--focus);outline-offset:3px}
html{-webkit-tap-highlight-color:transparent} /* no Android blue flash on taps; feedback comes from :active */
.pill:active,.way:active{scale:.97}
::placeholder{color:var(--muted);opacity:1}
.wrap{width:100%;max-width:calc(var(--container) + 2 * var(--page-x));margin-inline:auto;padding-inline:var(--page-x)}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ---------- type ---------- */
.eyebrow{display:block;font-family:var(--sans);font-weight:500;font-size:12px;line-height:1.2;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.h1,.h2{font-family:var(--font-head);font-weight:600;font-size:var(--fs-h2);line-height:1;letter-spacing:-.03em;margin:0;text-wrap:balance}
.h3{font-family:var(--font-head);font-weight:600;font-size:var(--fs-h3);line-height:1.15;letter-spacing:-.02em;margin:0}
.display{font-family:var(--font-head);font-weight:700;font-size:var(--fs-display);line-height:.95;letter-spacing:-.035em;margin:0}
.lede{font-size:var(--fs-lead);line-height:1.45;color:var(--muted);margin:0;max-width:36ch}
.kanji-eyebrow{display:flex;flex-wrap:wrap;align-items:baseline;row-gap:6px;font-family:var(--jp);font-weight:400;font-size:14px;line-height:1.4;letter-spacing:.3em;color:var(--muted)}
.kanji-eyebrow .dot{margin-left:.35em}
.kanji-eyebrow .en{margin-left:1.1em;font-family:var(--sans);font-weight:500;font-size:12px;letter-spacing:.08em;text-transform:uppercase}

/* ---------- section head row ---------- */
.section{padding-block:var(--section-y)}
.section+.section{padding-top:0}
.shead{display:grid;gap:16px var(--gap);margin-bottom:clamp(28px,3vw,48px)}
/* shelf heads (home): the products lead, the head steps back */
.shead--shelf{margin-bottom:clamp(24px,2.4vw,36px)}
.shead--shelf .shead__main{gap:12px}
.shead__main{display:flex;flex-direction:column;gap:16px;min-width:0}
@media(min-width:960px){
  .shead{grid-template-columns:repeat(12,minmax(0,1fr));align-items:end}
  .shead__main{grid-column:1/9}
  .shead>.lede,.shead>.shead__side{grid-column:9/13;padding-bottom:.35em}
  .belts-sec .shead>.lede{grid-column:1/9;padding-bottom:0} /* the belts subtitle sits under its heading, as on phones */
}

/* ---------- buttons ---------- */
.cta{display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:48px;padding:0 28px;font-family:var(--sans);font-size:16px;font-weight:500;line-height:1.2;letter-spacing:0;text-align:center;white-space:nowrap;border-radius:999px;border:1.5px solid transparent;transition:background-color .25s var(--ease-std),color .25s var(--ease-std),border-color .25s var(--ease-std),transform .15s var(--ease-std)}
.cta:active{transform:scale(.98)}
.cta--solid{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
@media(hover:hover){.cta--solid:hover{background:var(--accent-hover);border-color:var(--accent-hover);color:var(--accent-ink)}}
.cta--outline{border-color:var(--accent);color:var(--ink)}
@media(hover:hover){.cta--outline:hover{background:var(--surface)}}
.cta--lg{min-height:56px;padding:0 32px}
.cta--sm{min-height:44px;padding:0 22px;font-size:15px}
.cta--block{display:flex;width:100%}
.cta[disabled]{background:var(--hair);border-color:var(--hair);color:var(--ink-disabled);cursor:not-allowed;transform:none}
.ctas{display:flex;flex-wrap:wrap;gap:12px}

/* ---------- nav ---------- */
.nav{position:fixed;top:0;left:0;right:0;z-index:60;height:var(--nav-h);padding:0 var(--page-x);display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:16px;background:var(--paper);color:var(--ink);border-bottom:1px solid transparent;transition:border-color .25s var(--ease-std)}
.nav.is-stuck{border-bottom-color:var(--hair)}
.nav__brand{justify-self:start;display:flex;align-items:center;min-height:44px;min-width:44px}
.nav__brand .mark{width:32px;height:32px;object-fit:contain}
.nav__menu{display:flex;gap:32px}
.nav__menu a{position:relative;display:block;padding:10px 0;font-size:16px;font-weight:500;transition:color .15s var(--ease-std)}
.nav__menu a:hover{color:var(--muted)}
.nav__menu a::after{content:"";position:absolute;left:0;right:0;bottom:1px;height:2px;background:var(--ink);transform:scaleX(0);transform-origin:left;transition:transform .25s var(--ease-std)}
.nav__menu a[aria-current="page"]::after,.nav__menu a.is-here::after{transform:none}
.nav__end{justify-self:end;display:flex;align-items:center;gap:4px}
.nav__menubtn{display:none;width:44px;height:44px;place-items:center;border-radius:999px;color:inherit}
.nav__menubtn svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:square}
@media(max-width:959px){
  .nav{grid-template-columns:1fr auto}
  .nav__menu{display:none}
  .nav__menubtn{display:grid}
}

/* ---------- phone menu sheet (built by jj-nav.js) ---------- */
html.menu-open,html.menu-open body{overflow:hidden}
.sheet{position:fixed;inset:0;z-index:120;display:flex;flex-direction:column;padding:0 var(--page-x) 40px;background:var(--paper);color:var(--ink);overflow-y:auto;overscroll-behavior:contain}
.sheet[hidden]{display:none}
.sheet__top{flex:0 0 auto;height:var(--nav-h);display:flex;align-items:center;justify-content:space-between}
.sheet__top .mark{width:32px;height:32px}
.sheet__close{width:44px;height:44px;display:grid;place-items:center;border-radius:999px}
.sheet__close svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.6}
.sheet__links{list-style:none;margin:24px 0 0;padding:0}
.sheet__links li{border-bottom:1px solid var(--hair)}
.sheet__links a{display:block;padding:14px 0;font-family:var(--font-head);font-weight:600;font-size:32px;line-height:1.15;letter-spacing:-.02em}
.sheet__links a[aria-current="page"]{text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:6px}
.sheet__extra{display:flex;gap:28px;margin-top:32px}
.sheet__extra a{padding:10px 0;font-weight:500;color:var(--muted)}

/* ---------- hero ---------- */
#top{position:absolute;top:0;left:0}
.hero{position:relative;display:grid;grid-template-columns:minmax(0,1fr);background:var(--paper)}
.hero__inner{display:flex;flex-direction:column;align-items:flex-start;padding:clamp(32px,6vw,56px) var(--page-x) 36px;color:var(--ink)}
.hero__eyebrow{margin:0}
.wordmark{display:flex;flex-direction:column;margin:24px 0 0;font-family:var(--serif);font-weight:800;font-size:var(--fs-wordmark);line-height:.92;letter-spacing:.06em;text-transform:uppercase}
.wordmark .word{display:flex;overflow:hidden;padding-top:.14em;margin-top:-.14em}
.wordmark .ltr{display:inline-block}
.hero__tag{margin:24px 0 0;font-size:var(--fs-lead);line-height:1.45;color:var(--muted)}
.hero__ctas{margin-top:40px}
.hero__title{margin:24px 0 0}
.hero__media{position:relative;overflow:hidden;aspect-ratio:16/10;max-height:42svh;width:100%;background:var(--surface)}
.hero__bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 30%;filter:var(--grade)}
/* hero photos sit inside the page margins on phones too; home: the print first, then the wordmark and two buttons side by side */
@media(max-width:959px){.hero__media{width:auto;margin-inline:var(--page-x)}}
@media(max-width:767px){
  .hero--home .hero__inner{padding-top:28px;padding-bottom:4px}
  .hero--home .wordmark{margin-top:18px}
  .hero--home .hero__tag{margin-top:18px}
  .hero--home .hero__ctas{margin-top:28px}
}
@media(max-width:599px){
  .hero__ctas,.thanks__ctas{width:100%;display:grid;grid-template-columns:1fr 1fr;gap:8px}
  .hero__ctas .cta,.thanks__ctas .cta{width:100%;padding:0 10px}
  .hero__ctas .cta--lg{min-height:52px}
}
@media(min-width:960px){
  /* compact: the apparel shelf starts inside the first screen */
  /* the photo is framed on the page grid, like the products below it, instead of bleeding off the edge */
  .hero{grid-template-columns:repeat(2,minmax(0,1fr));column-gap:var(--gap);height:clamp(460px,calc(66svh - var(--nav-h)),600px);padding:clamp(12px,1.4vw,24px) max(var(--page-x),calc((100vw - var(--container)) / 2)) 0}
  .hero__inner{justify-content:center;padding:28px 48px 28px 0}
  .hero--home .wordmark{margin-top:20px;font-size:min(var(--fs-wordmark),7.2vw,12.5svh)}
  .hero--home .hero__tag{margin-top:20px}
  .hero--home .hero__ctas{margin-top:32px}
  .hero__media{aspect-ratio:auto;max-height:none}
}
/* home (v3b): the M3 opening over the H1 print. The tee's back print is the image, ink on white paper.
   The file is 640px wide (so it never shows wider) and painted from 6% to 89% of its height; the empty foot tucks under the type. */
.hero--home{--art-w:min(86vw,360px,calc((100svh - var(--nav-h)) * .41));grid-template-areas:"art" "copy";overflow:hidden}
/* inside the page margin (its right edge on the buttons' right edge): the print's grey wash fades out before the screen edge */
.hero__art{grid-area:art;position:relative;justify-self:end;width:var(--art-w);aspect-ratio:640/992;margin:8px var(--page-x) calc(var(--art-w) * -.15) 0;pointer-events:none}
.hero__art img{position:absolute;inset:0;width:100%;height:100%}
.hero--home .hero__inner{grid-area:copy;position:relative;padding-top:0}
.hero--home .wordmark{font-size:clamp(3.5rem,15vw + .25rem,8rem)}
.hero--home .hero__ctas{width:100%;flex-wrap:nowrap}
.hero--home .hero__ctas .cta{flex:1 1 0;padding:0 16px}
@media(min-width:600px){.hero--home .hero__ctas{width:auto}.hero--home .hero__ctas .cta{flex:0 0 auto;padding:0 32px}}
/* short phones (360x640, a 390x664 in-app browser): the print gives way (about half the screen) so both buttons sit above the fold */
@media(max-width:599px) and (max-height:760px){
  .hero--home{--art-w:min(86vw,calc(52svh * .645))}
  .hero--home .hero__art{margin-top:4px}
  .hero--home .wordmark{margin-top:14px;font-size:clamp(3.25rem,14vw,8rem)}
  .hero--home .hero__tag{margin-top:12px}
  .hero--home .hero__ctas{margin-top:20px}
}
/* tablet and desktop, and phones on their side: type left, the print right, in the compact hero (the apparel shelf starts on the first screen) */
@media(min-width:768px),(min-width:600px) and (max-height:540px) and (orientation:landscape){
  .hero--home{grid-template-columns:repeat(2,minmax(0,1fr));grid-template-areas:"copy art"}
  .hero--home .hero__ctas .cta{flex:0 0 auto;padding:0 32px}
  /* absolute inside its grid area: the painted part (6% to 89% of the file) centred on the hero, the empty foot runs off the bottom */
  .hero__art{position:absolute;top:calc(50% - var(--art-w) * .736);left:calc(50% - var(--art-w) * .5);margin:0}
}
@media(min-width:768px){
  .hero--home{--hero-h:clamp(460px,calc(66svh - var(--nav-h)),600px);--art-w:min(640px,40vw,calc(var(--hero-h) * .74));height:var(--hero-h)}
  .hero--home .wordmark{font-size:min(var(--fs-wordmark),7.2vw,12.5svh)}
}
/* tablet portrait: the desktop composition on a narrower grid (the type column a little wider than the print's) */
@media(min-width:768px) and (max-width:959px) and (min-height:541px){
  .hero--home{grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);column-gap:var(--gap);padding:12px var(--page-x) 0}
  .hero--home .hero__inner{justify-content:center;padding:0 16px 28px 0}
  .hero--home .wordmark{margin-top:20px;font-size:min(var(--fs-wordmark),9vw,12.5svh)}
  .hero--home .hero__tag{margin-top:20px}
  .hero--home .hero__ctas{margin-top:32px}
  .hero--home .hero__ctas .cta{padding:0 24px}
}
@media(min-width:600px) and (max-width:959px) and (max-height:540px) and (orientation:landscape){
  .hero--home{--art-w:calc((100svh - var(--nav-h)) * .72);column-gap:var(--gap);height:calc(100svh - var(--nav-h));padding:0 var(--page-x)}
  .hero--home .hero__inner{justify-content:center;padding:12px 0}
  .hero--home .wordmark{margin-top:10px;font-size:min(16svh + 1rem,9vw)}
  .hero--home .hero__tag{margin-top:10px}
  .hero--home .hero__ctas{margin-top:18px}
  .hero--home .hero__ctas .cta--lg{min-height:48px}
}
/* hero entrance hidden states: see MOTION (CSS keyframes with fill both, under html.js) */

/* ---------- apparel ---------- */
.drop{padding-block:var(--shelf-y)}
.drop__grid{display:grid;grid-template-columns:minmax(0,1fr);gap:48px var(--gap)}
@media(min-width:600px){.drop__grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:599px){.drop__grid{gap:40px}}
.pcard{display:flex;flex-direction:column;min-width:0}
/* photo slots: 4:5 (square on the two-up desktop row so a whole card fits one screen); any 4:5 photo drops in */
.pcard__media{position:relative;display:block;aspect-ratio:4/5;overflow:hidden;background:var(--surface);container-type:inline-size}
@media(min-width:960px){.pcard__media{aspect-ratio:1/1}}
.pcard__photo{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 34%;filter:var(--grade-product);transition:opacity .4s var(--ease-std),transform .8s var(--ease-out)}
.pcard__flat{position:absolute;inset:0;display:grid;place-items:center;opacity:0;transition:opacity .4s var(--ease-std)}
@media(hover:hover){
  .pcard--swap:hover .pcard__flat{opacity:1}
  .pcard--swap:hover .pcard__photo{opacity:0;transform:scale(1.03)}
}
.pcard__art{width:auto;max-width:66cqi;max-height:88%}
.pcard__chest{display:flex;flex-direction:column;align-items:center;gap:2.6cqi;width:100%;transform:translateY(-8%)}
.pcard__chest img{width:26cqi;margin-inline:auto}
.pcard__chest span{font-family:var(--jp);font-size:clamp(13px,4.4cqi,19px);letter-spacing:.3em;text-indent:.3em;color:#111}
.pcard__body{display:flex;flex-direction:column;flex:1;padding-top:14px}
.pcard__row{display:flex;align-items:baseline;justify-content:space-between;gap:16px}
.pcard__name{margin:0;font-family:var(--sans);font-size:16px;font-weight:500;line-height:1.4}
.pcard__price{font-size:16px;font-weight:500;white-space:nowrap}
.pcard__opts{margin-top:16px}
.pcard__buy{margin-top:auto;padding-top:12px}
.pcard__note{margin:8px 0 0}
/* two big tees: sizes and the button share one row */
@media(min-width:1200px){
  .drop .pcard__body{display:grid;grid-template-columns:minmax(0,1fr) minmax(200px,34%);align-items:center;column-gap:24px;padding-top:16px}
  .drop .pcard__row,.drop .pcard__note{grid-column:1/-1}
  .drop .pcard__name,.drop .pcard__price{font-size:18px}
  .drop .pcard__opts{margin-top:14px}
  .drop .pcard__buy{margin-top:14px;padding-top:0}
}

/* ---------- fighter cards: one shelf on the grey surface ----------
   Opens on a spread (from Direction B): the biggest headline on the page beside the two
   forged cards, pinned like collectibles. Then the builder. One spacing step (--shelf-y)
   between everything inside the shelf, so the spread, the builder and the edges line up.
   Phones: your card, then the steps, then the two buys (stage is display:contents).
   960+: your card and the buys stay on the left while the steps change on the right. */
/* bottom: the buys keep a status line under them (#forgeNote), so the visible gap to the Dojo band is one --shelf-y too */
.forge{padding-block:var(--shelf-y) max(24px,calc(var(--shelf-y) - 1.45em - 10px));background:var(--surface)}
.forge__open{display:grid;grid-template-columns:minmax(0,1fr);gap:0 var(--gap);margin-bottom:var(--shelf-y)}
.forge__head{display:flex;flex-direction:column;gap:16px;min-width:0}
.forge__head .h2{font-size:var(--fs-display);font-weight:700;line-height:.95;letter-spacing:-.035em}
.forge__head .lede{margin-top:4px}
.forge__more{min-width:0}
.forge__examples{display:flex;justify-content:center;align-items:flex-start;padding-top:clamp(28px,4vw,40px)}
.forge__examples img{position:relative;flex:0 1 auto;width:min(316px,44vw);image-rendering:pixelated;box-shadow:var(--shadow-card);transform:rotate(-4deg);transition:transform .6s var(--ease-out)}
.forge__examples img+img{z-index:1;width:min(286px,40vw);margin:clamp(36px,8vw,80px) 0 0 clamp(-48px,-5vw,-16px);transform:rotate(5deg)}
@media(hover:hover){.forge__examples img:hover{z-index:2;transform:rotate(0) translateY(-8px)}}
.forge__exlabel{margin:24px 0 0;text-align:center}
@media(min-width:960px){
  .forge__open{grid-template-columns:repeat(12,minmax(0,1fr));align-items:center}
  .forge__head{grid-column:1/6}
  .forge__more{grid-column:6/13}
  .forge__examples{padding-top:8px}
}
.forge__grid{display:flex;flex-direction:column;gap:24px}
.forge__stage{display:contents}
.forge__well{order:0;display:grid;place-items:center;min-width:0}
.forge__dock{width:min(100%,280px);perspective:1100px}
.forge__well .fc{max-width:none}
.forge .panel{order:1}
.forge__buy{order:2;display:flex;flex-direction:column;gap:10px}
@media(min-width:600px){.forge__dock{width:340px}}
@media(min-width:960px){
  .forge__grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:0 var(--gap);align-items:start}
  .forge__stage{--cw:min(420px,calc((100svh - var(--nav-h) - 200px) * .68));display:flex;flex-direction:column;gap:24px;grid-column:1/6;position:sticky;top:calc(var(--nav-h) + 24px)}
  .forge__well{justify-items:start}
  .forge__dock,.forge__buy{width:min(var(--cw),100%)}
  .forge .panel{grid-column:6/13}
}
.forge__buys{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.forge__buys .cta{padding:0 12px}
.forge__note{margin:0;text-align:center}
/* phones: once the card scrolls away, it docks small in the corner while you build (tap it to go back) */
.forge__dock.is-docked{position:fixed;z-index:50;bottom:calc(16px + env(safe-area-inset-bottom,0px));right:16px;transform:scale(.3);transform-origin:bottom right;cursor:pointer;animation:jj-dock .4s var(--ease-out)}
@keyframes jj-dock{from{opacity:0;transform:scale(.22)}to{opacity:1;transform:scale(.3)}}
.forge__up{display:none}
/* small phones: a slim bar along the bottom instead (the corner card sat on the chips): your card in miniature and an
   up arrow; a tap anywhere on it goes back to the card. The steps end with the bar's height so nothing stays under it */
@media(max-width:599px){
  .forge{--dock-h:68px}
  .forge__dock.is-docked{left:0;right:0;bottom:0;width:auto!important;height:calc(var(--dock-h) + env(safe-area-inset-bottom,0px));padding:0 var(--page-x) env(safe-area-inset-bottom,0px);display:flex;align-items:center;justify-content:flex-end;background:var(--paper);border-top:1px solid var(--hair);box-shadow:0 -16px 32px -24px rgba(17,17,17,.3);transform:none;animation:jj-dock-bar .4s var(--ease-out)}
  .forge__dock.is-docked .fc{position:absolute;left:var(--page-x);top:calc((var(--dock-h) - 412px * .125) / 2);width:280px;transform:none;scale:.125;transform-origin:0 0;box-shadow:0 12px 24px -8px rgba(17,17,17,.4);animation:none}
  .forge__dock.is-docked .forge__up{display:grid;place-items:center;width:44px;height:44px;border:1px solid var(--line);border-radius:50%;color:var(--ink)}
  .forge__up svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.6}
}
@keyframes jj-dock-bar{from{transform:translateY(100%)}to{transform:none}}

.panel{min-width:0}
.forge .panel{background:var(--paper);padding:32px clamp(20px,2.4vw,32px)}
.prow{padding:32px 0;border-top:1px solid var(--hair)}
.prow:first-child{padding-top:0;border-top:0}
.prow:last-child{padding-bottom:0}
.prow__head{display:flex;align-items:baseline;gap:14px;margin-bottom:24px}
.prow__num{flex:0 0 auto;font-size:12px;font-weight:500;letter-spacing:.08em;color:var(--muted)}
.prow__title{margin:0;font-family:var(--font-head);font-weight:600;font-size:var(--fs-h3);line-height:1.15;letter-spacing:-.02em}
.prow__grid{display:grid;grid-template-columns:minmax(0,1fr);gap:0 16px}
@media(min-width:600px){.prow__grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
.prow__hint{margin:14px 0 0;font-size:14px;color:var(--muted)}

/* the steps as a stepper: jj-forge.js adds .is-stepper; without JS every step stays open as above */
.forge .panel.is-stepper{padding-block:4px}
@media(max-width:599px){.forge .panel.is-stepper{padding-bottom:calc(var(--dock-h) + 4px)}} /* the steps end clear of the phone dock bar */
.panel.is-stepper .prow,.panel.is-stepper .prow:first-child,.panel.is-stepper .prow:last-child{padding:0}
.panel.is-stepper .prow:first-child{border-top:0}
.panel.is-stepper .prow__head{display:block;margin:0}
.panel.is-stepper .prow__title{font-size:inherit;letter-spacing:0;line-height:1.2}
.prow__toggle{display:flex;align-items:center;gap:14px;width:100%;min-height:72px;padding:14px 0;text-align:left;color:var(--ink)}
.prow__toggle .prow__num{min-width:2.2em}
.prow__label{font-family:var(--font-head);font-weight:600;font-size:clamp(19px,1.05rem + .35vw,23px);letter-spacing:-.015em}
.prow__sum{display:flex;align-items:center;gap:8px;min-width:0;margin-left:auto;font-family:var(--sans);font-size:14px;font-weight:500;color:var(--muted);white-space:nowrap}
.prow__sum span{overflow:hidden;text-overflow:ellipsis}
.prow__sum i{flex:0 0 auto;width:12px;height:12px;border-radius:50%}
.prow__chev{flex:0 0 auto;width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.6;transition:transform .35s var(--ease-out)}
.prow.is-open .prow__chev{transform:rotate(180deg)}
.prow.is-open .prow__sum{visibility:hidden}
.prow__toggle:hover .prow__label{color:var(--muted)}
.prow.is-open .prow__toggle:hover .prow__label{color:var(--ink)}
.panel.is-stepper .prow:not(.is-open) .prow__body{display:none}
.panel.is-stepper .prow__body{padding:4px 0 32px}
@keyframes jj-open{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
.panel.is-stepper .prow.is-open .prow__body{animation:jj-open .45s var(--ease-out)}
.field{display:flex;flex-direction:column;gap:8px;margin-bottom:20px;min-width:0}
.field label,.field .field__lbl{font-size:14px;font-weight:500;color:var(--ink)}
.field--discs{margin:4px 0 0}
.field input{width:100%;height:52px;padding:0 16px;font-family:var(--sans);font-size:16px;color:var(--ink);background:var(--paper);border:1px solid var(--line-strong);border-radius:8px;transition:border-color .15s var(--ease-std),box-shadow .15s var(--ease-std)}
.field input:focus{outline:none;border-color:var(--ink);box-shadow:0 0 0 1px var(--ink),0 0 0 4px rgba(17,17,17,.12)}
.fsel select{width:100%;height:52px;padding:0 44px 0 16px;font-size:16px;font-weight:400;letter-spacing:0;text-transform:none;border:1px solid var(--line-strong);border-radius:8px;background:var(--paper);color:var(--ink)}
.fsel select:focus{outline:none;border-color:var(--ink);box-shadow:0 0 0 1px var(--ink),0 0 0 4px rgba(17,17,17,.12)}
.fsel::after{right:20px;border-color:var(--ink)}

/* chips: discipline + stat pills (same component as the size chips) */
.pillrow{display:flex;flex-wrap:wrap;gap:8px}
.pill{display:inline-flex;align-items:center;min-height:44px;padding:0 16px;font-size:14px;font-weight:500;color:var(--ink);border:1px solid var(--line);border-radius:999px;transition:background-color .15s var(--ease-std),border-color .15s var(--ease-std),color .15s var(--ease-std)}
.pill:hover{border-color:var(--ink)}
.pill[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.pill:disabled{color:var(--ink-disabled);border-color:var(--hair);cursor:not-allowed}
.pill--input{padding:0;border-style:dashed;border-color:var(--line-strong);background:transparent}
.pill--input input{min-width:200px;width:auto;min-height:44px;padding:0 18px;font-family:var(--sans);font-size:16px;font-weight:500;color:var(--ink);background:transparent;border:0;border-radius:999px}
.pill--input input:focus{outline:none}
.pill--input:focus-within{border-color:var(--ink);border-style:solid}
.pill--input input:disabled{opacity:.4}
.pill--own{gap:8px}
.pill--own i{font-style:normal;font-size:10px;opacity:.7}

.scores{display:grid;grid-template-columns:minmax(0,1fr);gap:0 28px;margin-top:16px}
@media(min-width:600px){.scores{grid-template-columns:repeat(2,minmax(0,1fr))}}
.score{display:grid;grid-template-columns:1fr auto auto auto;align-items:center;gap:10px;padding:8px 0;border-top:1px solid var(--hair)}
.score__name{font-size:14px;font-weight:500}
.score__val{min-width:2.4ch;font-family:var(--font-head);font-weight:600;font-size:18px;text-align:center;font-variant-numeric:tabular-nums}
.score button{width:40px;height:40px;display:grid;place-items:center;font-size:18px;line-height:1;border:1px solid var(--line);border-radius:50%;transition:border-color .15s,background-color .15s,color .15s}
.score button:hover{border-color:var(--ink)}

.drop-zone{position:relative;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:12px;min-height:140px;padding:24px;background:var(--surface);border:1px dashed var(--line-strong);border-radius:12px;transition:border-color .2s var(--ease-std)}
.drop-zone:hover{border-color:var(--ink)}
.drop-zone.is-set{border-style:solid;border-color:var(--ink)}
.drop-zone input[type=file]{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
.drop-zone label{display:inline-flex;align-items:center;min-height:48px;padding:0 24px;font-size:16px;font-weight:500;border:1.5px solid var(--ink);border-radius:999px;background:var(--paper);cursor:pointer;transition:background-color .2s var(--ease-std)}
.drop-zone label:hover{background:var(--surface-hover)}
.drop-zone input:focus-visible+label{outline:2px solid var(--focus);outline-offset:3px}
.drop-zone__txt{margin:0;font-size:14px;line-height:1.5;color:var(--muted)}

.ways{display:flex;flex-wrap:wrap;gap:20px;margin:0}
.way{display:flex;flex-direction:column;align-items:center;gap:10px;padding:0}
.way i{display:block;width:40px;height:40px;border-radius:50%;transition:box-shadow .2s var(--ease-std)}
.way span{font-size:12px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.way:hover i{box-shadow:0 0 0 3px var(--paper),0 0 0 4px var(--line)}
.way[aria-pressed="true"] i{box-shadow:0 0 0 3px var(--paper),0 0 0 5px var(--ink)}
.way[aria-pressed="true"] span{color:var(--ink)}

/* ===== HOME MOTION (v4) — begin ===== */
/* The home page as one journey, in the opening's language: ink on paper. jj-home.js adds html.hm (never under reduced
   motion); without it every rule here is inert and the page shows its final state. Nothing loops.
   - the surfaces arrive as ink: the grey Fighter Cards shelf and the dark Dojo band rise into the page behind a brushed
     edge, led by the scroll and finishing on its own once it starts (.hm-wash: the previous surface, pulled up off the new one)
   - the tee photos soak down from the top like the print's figure in the opening (.hm-soak); the flat print opens as an
     ink drop from the pointer (desktop) or slides over the photo as you swipe (phones); a size fills with ink from your tap
   - the section headings rise out of their line, like the wordmark
   - the cards are dealt: the forged pair fans out of a stack, your card comes off the deck and straightens; a pick strikes it
   - the Next Drop answers with the seal */
@property --hm-r{syntax:"<percentage>";inherits:false;initial-value:0%}

/* the brushed edge: a 2400x120 tile drawn with SVG turbulence (a slow wave, the ragged fibres of the paper, a half-tone where the ink thins),
   repeated across; the paper above it is solid. Flipped (scaleY -1) it soaks downward. */
.hm-wash,.hm-soak{position:absolute;left:0;right:0;display:block;pointer-events:none;will-change:transform;
  --hm-edge:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='2400' height='120'%3E%3Cfilter id='a' x='-.05' y='-.2' width='1.1' height='1.4'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.0035 .002' numOctaves='2' seed='5' result='w'/%3E%3CfeDisplacementMap in='SourceGraphic' in2='w' scale='72' yChannelSelector='G' result='s'/%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.02 .008' numOctaves='5' seed='9'/%3E%3CfeDisplacementMap in='s' scale='26' yChannelSelector='G'/%3E%3CfeGaussianBlur stdDeviation='1.6'/%3E%3C/filter%3E%3Cfilter id='b' x='-.05' y='-.2' width='1.1' height='1.4'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.0035 .002' numOctaves='2' seed='5' result='w'/%3E%3CfeDisplacementMap in='SourceGraphic' in2='w' scale='72' yChannelSelector='G' result='s'/%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.05 .01' numOctaves='5' seed='9'/%3E%3CfeDisplacementMap in='s' scale='20' yChannelSelector='G'/%3E%3CfeGaussianBlur stdDeviation='0.4'/%3E%3C/filter%3E%3Crect x='-80' y='-80' width='2560' height='148' opacity='.4' filter='url(%23a)'/%3E%3Crect x='-80' y='-80' width='2560' height='142' filter='url(%23b)'/%3E%3C/svg%3E");
  -webkit-mask-image:var(--hm-edge),linear-gradient(#000,#000);mask-image:var(--hm-edge),linear-gradient(#000,#000);
  -webkit-mask-size:2400px 120px,100% calc(100% - 118px);mask-size:2400px 120px,100% calc(100% - 118px);
  -webkit-mask-position:0 100%,0 0;mask-position:0 100%,0 0;-webkit-mask-repeat:repeat-x,no-repeat;mask-repeat:repeat-x,no-repeat}
html.js.hm .hm-sec{position:relative;isolation:isolate}
html.js.hm .forge.hm-sec{overflow:clip} /* the paper leaves upward: clipped at the shelf's top edge */
.hm-wash{top:0;z-index:-1;height:calc(25vh + 120px)}
.hm-wash--forge{background:var(--paper)}
.hm-wash--dojo{background:#f5f5f5} /* the Fighter Cards surface (--surface on :root; the band redefines it) */
.hm-soak{top:-100px;z-index:2;height:calc(100% + 100px);background:var(--paper);transform:scaleY(-1)}

/* headings rise out of their line (the box never moves: no layout shift) */
.hm-line{display:block;overflow:hidden;padding-block:.1em;margin-block:-.1em}
.hm-rise{display:block}
html.js.hm .hm-wait .hm-rise{transform:translateY(112%)}
html.js.hm .hm-go .hm-rise{transition:transform .95s var(--ease-out)}

/* apparel: the flat print opens as an ink drop from where the pointer came in, and closes back to where it left;
   the photo stays under it (no cross-fade). Phones keep the swipe (jj-home.js slides the print over the photo). */
@media(hover:hover){
  html.js.hm .pcard--swap .pcard__flat{opacity:1;background:var(--surface);transition:--hm-r .75s var(--ease-out);
    -webkit-mask-image:radial-gradient(circle at var(--hx,50%) var(--hy,50%),#000 calc(var(--hm-r) - 12%),transparent var(--hm-r));
    mask-image:radial-gradient(circle at var(--hx,50%) var(--hy,50%),#000 calc(var(--hm-r) - 12%),transparent var(--hm-r))}
  html.js.hm .pcard--swap:hover .pcard__flat{--hm-r:150%}
  html.js.hm .pcard--swap:hover .pcard__photo{opacity:1}
}
/* a size fills with ink from the point you pressed; the last one drains as the new one fills */
html.js.hm .size{isolation:isolate;transition:border-color .15s var(--ease-std),color .2s var(--ease-std) .05s,scale .12s var(--ease-std)}
html.js.hm .size::before{content:"";position:absolute;z-index:-1;left:var(--sx,50%);top:var(--sy,50%);width:300%;aspect-ratio:1;border-radius:50%;background:var(--ink);translate:-50% -50%;scale:0;transition:scale .5s var(--ease-out)}
html.js.hm .size[aria-pressed="true"]{background:var(--ink);transition:border-color .15s var(--ease-std),color .2s var(--ease-std) .05s,scale .12s var(--ease-std),background-color 0s .45s} /* snaps solid once the ink lands: no hairline ring */
html.js.hm .size[aria-pressed="true"]::before{scale:1}
html.js.hm .size:active{scale:.94}

/* fighter cards: tap a forged card to lift it (the touch twin of the hover) */
html.js.hm .forge__examples img.hm-up{z-index:2;transform:rotate(0) translateY(-8px)}
/* a pick strikes your card: the stamp (jj-forge.js) and a glint of light across it */
html.js.hm .fc::before{content:"";position:absolute;inset:0;z-index:4;pointer-events:none;opacity:0;background:linear-gradient(105deg,transparent 38%,rgba(255,255,255,.34) 50%,transparent 62%) 100% 0/300% 100% no-repeat}
@keyframes hm-glint{from{opacity:1;background-position:100% 0}to{opacity:1;background-position:0 0}}
html.js.hm .fc.hm-glint::before{animation:hm-glint .75s var(--ease-std)}

/* next drop: the field draws its ring in; a yes rises in, a no shakes its head (jj-home.js) */
html.js.hm .cap__form input{transition:border-color .2s var(--ease-std),box-shadow .5s var(--ease-out)}
html.js.hm .cap__msg.hm-say{animation:jj-up .5s var(--ease-out) both}
/* ===== HOME MOTION (v4) — end ===== */

/* ---------- the fighter card (colours come from jj-forge.js) ---------- */
.fc{width:100%;max-width:400px;aspect-ratio:316/465;padding:3.4%;position:relative;font-family:var(--px);color:#fff;background:var(--fc-outer,#8b52c9);box-shadow:var(--shadow-card);transition:background .5s ease}
.fc__frame{position:absolute;inset:3.4%;border:3px solid var(--fc-line,#e3c8ff);background:var(--fc-inner,#2a1240);display:flex;flex-direction:column;gap:2.4%;padding:4.4% 4.6%}
.fc__frame::before,.fc__frame::after{content:"";position:absolute;width:11px;height:11px;border:3px solid var(--fc-line,#e3c8ff);top:6px}
.fc__frame::before{left:6px;border-right:0;border-bottom:0}
.fc__frame::after{right:6px;border-left:0;border-bottom:0}
.fc__plate{border:3px solid var(--fc-line,#e3c8ff);background:var(--fc-plate,#3d1c5c);padding:5% 6%;text-align:center;font-size:clamp(8px,2.5vw,11px);line-height:1.35;letter-spacing:.02em;overflow-wrap:anywhere}
.fc__plate--name{background:#141018}
.fc__plate--nick{font-size:clamp(8px,2.4vw,11px)}
.fc__art{flex:1;position:relative;border:3px solid var(--fc-line,#e3c8ff);background:linear-gradient(170deg,var(--fc-art-a,#3a1a55),var(--fc-art-b,#150a22));overflow:hidden;display:grid;place-items:center}
.fc__art::before{content:"";position:absolute;inset:0;background-image:repeating-linear-gradient(0deg,rgba(255,255,255,.06) 0 1px,transparent 1px 4px),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 4px)}
.fc__artnote{position:relative;margin:0;padding:0 10%;font-family:var(--sans);font-size:9px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.6);text-align:center;line-height:1.9}
.fc__art.has-photo{background-size:cover;background-position:center 22%}
.fc__art.has-photo::before{background-image:repeating-linear-gradient(0deg,rgba(0,0,0,.22) 0 1px,transparent 1px 4px),repeating-linear-gradient(90deg,rgba(0,0,0,.18) 0 1px,transparent 1px 4px)}
.fc__art.has-photo .fc__artnote{display:none}
.fc__art.has-photo::after{content:"reference photo";position:absolute;bottom:5px;left:0;right:0;text-align:center;font-family:var(--sans);font-size:7px;letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.72);text-shadow:0 1px 3px rgba(0,0,0,.9)}
.fc__stats{display:grid;grid-template-columns:1fr auto 1fr;grid-template-rows:auto auto;gap:3% 4%;align-items:center}
.fc__stat{display:flex;align-items:center;gap:5px;border:2px solid var(--fc-line,#e3c8ff);background:var(--fc-plate,#3d1c5c);padding:5% 6%;font-size:clamp(6px,1.7vw,8px);letter-spacing:.02em;line-height:1.25}
.fc__stat b{font-weight:400;color:var(--fc-num,#ffd76a);flex:0 0 auto}
.fc__stat--r{flex-direction:row-reverse}
.fc__stat span{opacity:.92;overflow-wrap:anywhere}
.fc__flag{grid-area:1/2/3/3;display:grid;place-items:center;align-self:center}
.fc__flag i{width:34px;height:34px;border-radius:50%;border:2px solid var(--fc-line,#e3c8ff);background:var(--fc-plate,#3d1c5c);display:grid;place-items:center;color:var(--fc-line,#e3c8ff)}
.fc__flag svg{width:21px;height:21px;shape-rendering:crispEdges}
.fc__banner{border:3px solid var(--fc-line,#e3c8ff);background:var(--fc-plate,#3d1c5c);border-radius:999px;padding:4.4% 6%;text-align:center;font-size:clamp(9px,2.7vw,13px);letter-spacing:.04em}
.fc__empty{opacity:.4}

/* ---------- the Dojo map band (home #dojo + dojo.html opener) ---------- */
.dojo{position:relative;padding-block:var(--section-y);overflow:hidden}
.dojo__head{position:relative;z-index:2;display:flex;flex-direction:column;gap:16px;pointer-events:none}
.dojo__head>*{pointer-events:auto}
.dmap{position:relative;margin:clamp(-72px,-4.5vw,-8px) 0 0}
.dmap__scroll{overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}
.dmap__scroll::-webkit-scrollbar{display:none}
.dmap__canvas{position:relative;width:100%;max-width:1760px;margin-inline:auto;aspect-ratio:1000/361.1;container-type:inline-size}
@media(max-width:959px){.dmap__scroll{padding-inline:var(--page-x)}.dmap__canvas{width:max(100%,1100px)}}
/* 960+: the map gives way on shorter screens so the headline, the map, the stats and the button share one screen;
   it tucks under the headline only a little, so the northern dots stay clear of the type */
@media(min-width:960px){.dmap{margin-top:-24px}.dmap__canvas{max-width:min(1760px,max(640px,calc((100svh - 460px) * 2.7693)))}}
.dmap__canvas>img,.dmap__canvas>svg{position:absolute;inset:0;display:block;width:100%;height:100%}
.dmap__land{stroke:var(--map-land)}
.dmap__arc{fill:none;stroke:var(--ink);stroke-opacity:.3;stroke-width:.8;transition:stroke-opacity .3s var(--ease-std)}
.dmap__halo{fill:var(--ink);fill-opacity:.1}
.dmap__dot{fill:var(--ink)}
.dmap__ring{fill:none;stroke:var(--ink);stroke-opacity:.5;stroke-width:.8}
.dmap.has-focus .dmap__arc{stroke-opacity:.12}
.dmap.has-focus .dmap__arc.is-hot{stroke-opacity:.95;stroke-width:1.4}
.dmap__region.is-hot .dmap__halo{fill-opacity:.24}
.dmap__nodes{position:absolute;inset:0}
.dmap__node{position:absolute;width:36px;height:36px;margin:-18px 0 0 -18px;border-radius:50%;color:var(--ink)}
.dmap__node:focus-visible{outline:2px solid var(--focus);outline-offset:0}
.dmap__n{position:absolute;left:calc(50% + var(--r) * .1cqi + 5px);top:50%;transform:translateY(-50%);font-size:13px;font-weight:500;line-height:1;color:var(--ink);pointer-events:none;font-variant-numeric:tabular-nums}
.dmap__tip{position:absolute;z-index:3;left:0;top:0;padding:8px 14px;font-size:13px;font-weight:500;line-height:1.2;white-space:nowrap;color:var(--paper);background:var(--ink);border-radius:999px;pointer-events:none;transform:translate(-50%,calc(-100% - 14px));opacity:0;transition:opacity .2s var(--ease-std)}
.dmap__tip.is-on{opacity:1}
.dmap__tip.is-below{transform:translate(-50%,14px)}
.dmap__tip.is-left{transform:translate(calc(-100% + 18px),calc(-100% - 14px))}
.dmap__tip.is-right{transform:translate(-18px,calc(-100% - 14px))}
.dojo__foot{position:relative;z-index:2;display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:32px 48px;margin-top:clamp(24px,3vw,48px)}
.stats{display:flex;flex-wrap:wrap;gap:24px clamp(20px,5vw,80px);margin:0}
.stat{display:flex;flex-direction:column-reverse;gap:10px}
.stat dt{font-size:12px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.stat dd{margin:0;font-family:var(--font-head);font-weight:700;font-size:var(--fs-display);line-height:.9;letter-spacing:-.035em;font-variant-numeric:tabular-nums}
.dojo--page .dojo__head .h1{font-size:var(--fs-display);font-weight:700;line-height:.95;letter-spacing:-.035em}
@media(max-width:599px){
  .dojo__foot .cta{width:100%}
  .stats{display:grid;grid-template-columns:repeat(3,auto);justify-content:space-between;width:100%;gap:24px 12px}
  .stat:nth-child(2){align-items:center}
}
@media(max-width:419px){.stat dd{font-size:min(var(--fs-display),11vw)}}

/* ---------- dojo.html: belts, inside, photos, join ---------- */
.belts{list-style:none;margin:0;padding:0;display:grid;gap:clamp(12px,1.4vw,18px)}
.belt{display:grid;grid-template-columns:minmax(0,1fr);align-items:center;gap:8px 16px}
@media(min-width:600px){.belt{grid-template-columns:5.5rem 10rem minmax(0,1fr)}}
.belt__lvl{font-size:12px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.belt__name{font-family:var(--font-head);font-weight:600;font-size:clamp(18px,1.5vw,22px);line-height:1.2;letter-spacing:-.01em}
.belt__lbl{display:flex;align-items:baseline;gap:12px}
@media(min-width:600px){.belt__lbl{display:contents}}
.belt__track{position:relative;height:clamp(16px,1.7vw,24px)}
.belt__bar{position:absolute;left:0;top:0;bottom:0;width:calc(var(--lvl) / 9 * 100%);background:var(--belt);border-radius:2px;transform-origin:left center}
.belt__bar::after{content:"";position:absolute;top:0;bottom:0;right:clamp(4px,6%,40px);width:clamp(8px,10%,48px);background:var(--tip,#111)}
.belt--white .belt__bar{box-shadow:inset 0 0 0 1px var(--line)}
.belt--black{--tip:#c0463c}
.belt--jiyu .belt__bar{box-shadow:0 0 0 1px rgba(17,17,17,.06)}

.tiles{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:minmax(0,1fr);gap:0 var(--gap)}
@media(min-width:600px){.tiles{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:960px){.tiles{grid-template-columns:repeat(4,minmax(0,1fr))}}
.tile{padding:20px 0 40px;border-top:1.5px solid var(--ink)}
.tile__n{display:block;margin-bottom:16px;font-size:12px;font-weight:500;letter-spacing:.08em;color:var(--muted);font-variant-numeric:tabular-nums}
.tile__t{margin:0 0 10px;font-family:var(--font-head);font-weight:600;font-size:var(--fs-h3);line-height:1.15;letter-spacing:-.02em}
.tile__p{margin:0;max-width:30ch;color:var(--muted)}
@media(max-width:599px){.tile{padding:16px 0 28px}}

.join{padding-block:var(--section-y)}
.join__in{display:flex;flex-direction:column;align-items:flex-start;gap:32px;padding-top:clamp(32px,4vw,48px);border-top:1.5px solid var(--ink)}
.join__price{margin:0;font-family:var(--font-head);font-weight:700;font-size:var(--fs-display);line-height:.95;letter-spacing:-.035em}
.join__per{font-size:.42em;font-weight:600;letter-spacing:-.02em;color:var(--muted)}
.join__note{margin:16px 0 0;font-size:var(--fs-lead);color:var(--muted)}
@media(max-width:599px){.join__in .cta{width:100%}}

/* ===== DOJO MOTION (v4) — begin ===== */
/* dojo.html, thanks.html and the footer on every page. One language with the home opening: ink that paints.
   The map band bleeds into the paper; the belt ladder is earned as you scroll (each belt paints in as it crosses the
   reading line and the latest one lifts, in its own colour); the four tiles draw their rules in order; Join is signed
   with one brush stroke and the price inks in; on thanks.html the same stroke paints under "It's done." Hover answers on a mouse, a tap on a phone.
   Every hidden starting state on dojo.html hangs off a class jj-dojo-page.js adds (.is-bleed, .is-ladder, .is-ink), never off
   html.js alone (thanks.html is pure CSS under html.js): without JS, if the script fails, or under reduced motion (it adds none of them) the page is simply finished.
   Nothing loops. No GSAP. */
@keyframes jj-dj-sheen{from{background-position:100% 0;opacity:1}to{background-position:0 0;opacity:1}}
@keyframes jj-dj-ring{from{box-shadow:0 0 0 0 rgba(17,17,17,.32)}to{box-shadow:0 0 0 16px rgba(17,17,17,0)}}
@keyframes jj-dj-wipe{from{-webkit-mask-position:100% 0;mask-position:100% 0}to{-webkit-mask-position:0 0;mask-position:0 0}}
@keyframes jj-dj-settle{from{opacity:0;translate:0 .06em}to{opacity:1;translate:none}}
@keyframes jj-dj-blink{0%,100%{transform:none}28%{transform:scaleY(.1)}62%{transform:scaleY(1.06)}}

/* the hand-over: the band ends in the underside of one dry brush stroke (the same brush that signs Join below):
   deep at the left where the brush came in, lifting and breaking into dry streaks to the right. With .is-bleed it is
   dragged across, left to right, the first time it comes into view (.is-bled) */
.belts-sec{position:relative}
.belts-sec::before{content:"";position:absolute;left:0;right:0;top:0;height:40px;pointer-events:none;background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 240' preserveAspectRatio='none'%3E%3Cpath fill='%23111' d='M0 0L1200 0L1200 14L0 14ZM0 -11L3 -11L8 -11L15 -11L24 -11L30 -11L60 -12L90 -12L120 -13L150 -13L180 -13L210 -14L240 -14L270 -14L300 -14L330 -14L360 -14L390 -14L420 -14L450 -14L480 -14L510 -13L540 -13L570 -13L600 -12L630 -12L660 -11L690 -10L720 -10L750 -9L780 -8L810 -8L840 -7L870 -6L900 -6L930 -5L960 -5L990 -4L1020 -4L1050 -4L1080 -4L1110 -4L1140 -4L1170 -4L1200 1L1200 5L1170 10L1140 10L1110 10L1080 11L1050 11L1020 11L990 12L960 13L930 14L900 16L870 17L840 19L810 21L780 22L750 24L720 26L690 28L660 29L630 31L600 32L570 34L540 35L510 36L480 37L450 37L420 38L390 38L360 38L330 38L300 38L270 38L240 37L210 36L180 36L150 35L120 34L90 32L60 31L30 30L24 29L15 29L8 29L3 28L0 28ZM0 14L3 14L8 14L15 14L24 15L30 15L60 15L90 16L120 17L150 17L180 18L210 18L240 19L270 19L300 19L330 19L360 19L390 19L420 19L450 19L480 18L510 18L540 17L570 17L600 16L630 15L660 15L690 14L720 13L750 12L780 11L810 10L840 9L870 9L900 8L930 7L960 6L990 6L1020 6L1050 5L1080 5L1110 5L1140 5L1170 5L1200 8L1200 10L1170 14L1140 14L1110 14L1080 15L1050 15L1020 15L990 16L960 17L930 19L900 21L870 24L840 26L810 28L780 31L750 33L720 36L690 38L660 40L630 42L600 44L570 46L540 48L510 49L480 50L450 51L420 52L390 53L360 53L330 53L300 52L270 52L240 51L210 50L180 49L150 48L120 46L90 44L60 43L30 41L24 40L15 40L8 39L3 39L0 39ZM0 32L3 32L8 32L15 33L24 33L30 33L60 35L90 36L120 38L150 39L180 40L210 41L240 42L270 42L300 43L330 43L360 43L390 43L420 43L450 42L480 41L510 40L540 39L570 38L600 36L630 35L660 33L690 31L720 29L750 27L780 25L810 23L840 21L870 19L900 17L930 16L960 14L990 13L1020 12L1050 12L1080 12L1110 12L1140 12L1170 11L1200 14L1200 17L1170 20L1140 21L1110 21L1080 21L1050 22L1020 22L990 23L960 25L930 28L900 31L870 34L840 38L810 41L780 45L750 48L720 52L690 55L660 59L630 62L600 65L570 67L540 70L510 72L480 73L450 75L420 76L390 76L360 77L330 77L300 76L270 75L240 74L210 73L180 71L150 69L120 67L90 65L60 62L30 59L24 59L15 58L8 57L3 57L0 56ZM0 49L3 50L8 50L15 51L24 51L30 52L60 54L90 57L120 59L150 61L180 62L210 64L240 65L270 66L300 67L330 67L360 67L390 67L420 66L450 65L480 64L510 63L540 61L570 59L600 56L630 54L660 51L690 48L720 45L750 42L780 39L810 36L840 33L870 36L870 39L840 50L810 54L780 59L750 64L720 68L690 73L660 77L630 81L600 85L570 88L540 91L510 94L480 96L450 98L420 99L390 100L360 101L330 101L300 100L270 99L240 98L210 96L180 94L150 91L120 88L90 85L60 81L30 78L24 77L15 76L8 75L3 74L0 74ZM1050 23L1080 19L1110 18L1140 18L1170 18L1200 21L1200 23L1170 27L1140 27L1110 28L1080 28L1050 25ZM0 67L3 67L8 68L15 69L24 70L30 70L60 74L90 77L120 80L150 82L180 85L210 87L240 88L270 90L300 91L330 91L360 91L390 91L420 90L450 89L480 87L510 85L540 83L570 80L600 77L630 73L660 70L690 66L720 62L750 57L780 53L810 49L840 45L870 41L900 37L930 33L960 34L960 37L930 46L900 50L870 56L840 61L810 67L780 73L750 79L720 84L690 90L660 95L630 100L600 105L570 109L540 113L510 116L480 119L450 121L420 123L390 124L360 125L330 125L300 124L270 123L240 121L210 119L180 116L150 113L120 109L90 105L60 101L30 96L24 95L15 94L8 93L3 92L0 92ZM0 85L3 85L8 86L15 87L24 88L30 89L60 93L90 97L120 101L150 104L180 107L210 109L240 112L270 113L300 114L330 115L360 115L390 115L420 114L450 112L480 122L480 130L450 145L420 147L390 148L360 149L330 149L300 148L270 146L240 144L210 141L180 138L150 134L120 130L90 125L60 120L30 115L24 114L15 112L8 111L3 110L0 109ZM540 116L570 101L600 97L630 93L660 88L690 83L720 86L720 92L690 107L660 114L630 120L600 125L570 130L540 123ZM0 102L3 103L8 104L15 105L24 106L30 107L60 112L90 117L120 121L150 126L180 129L210 132L240 135L270 137L300 138L330 139L360 139L390 139L420 137L450 135L480 133L510 130L540 126L570 122L600 117L630 112L660 106L690 100L720 94L750 96L750 101L720 117L690 124L660 132L630 139L600 145L570 151L540 156L510 161L480 165L450 168L420 170L390 172L360 173L330 173L300 172L270 170L240 167L210 164L180 160L150 156L120 151L90 145L60 139L30 133L24 132L15 130L8 129L3 128L0 127ZM930 55L960 46L990 42L1020 40L1050 43L1050 45L1020 50L990 52L960 57L930 58ZM0 120L3 121L8 122L15 123L24 125L30 126L60 132L90 137L120 142L150 147L180 151L210 155L240 158L270 160L300 162L330 163L360 163L390 162L420 161L450 159L480 156L510 152L540 148L570 143L600 137L630 131L660 125L690 118L720 110L750 111L750 116L720 133L690 142L660 150L630 158L600 165L570 172L540 178L510 183L480 188L450 191L420 194L390 196L360 197L330 196L300 195L270 193L240 191L210 187L180 183L150 177L120 172L90 166L60 159L30 152L24 150L15 148L8 147L3 145L0 145ZM0 138L3 138L8 139L15 141L24 143L30 144L60 151L90 157L120 163L150 169L180 174L210 178L240 181L270 184L300 186L330 187L360 187L390 186L420 185L450 182L480 179L510 175L540 181L540 189L510 206L480 211L450 215L420 218L390 220L360 221L330 220L300 219L270 217L240 214L210 210L180 205L150 199L120 193L90 186L60 178L30 170L24 169L15 166L8 164L3 163L0 162ZM900 81L930 73L930 76L900 84Z'/%3E%3C/svg%3E") 0 0/100% 100% no-repeat}
@media(max-width:599px){.belts-sec::before{height:24px}}
.belts-sec.is-bleed::before{-webkit-mask:linear-gradient(90deg,#000 48%,transparent 52%) 100% 0/220% 100% no-repeat;mask:linear-gradient(90deg,#000 48%,transparent 52%) 100% 0/220% 100% no-repeat;
  transition:-webkit-mask-position 1.2s cubic-bezier(.55,0,.25,1),mask-position 1.2s cubic-bezier(.55,0,.25,1)}
.belts-sec.is-bleed.is-bled::before{-webkit-mask-position:0 0;mask-position:0 0}

/* the belts: lift on hover (mouse) or tap (.is-picked), a sheen of light runs along, a glow of the belt's own colour under it */
.belt{cursor:default;-webkit-tap-highlight-color:transparent}
.belt__bar{z-index:1;transition:transform .5s var(--ease-out)}
.belt__bar::before{content:"";position:absolute;inset:0;border-radius:inherit;opacity:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 38%,rgba(255,255,255,.55) 50%,transparent 62%) 100% 0/300% 100% no-repeat}
.belt__track::after{content:"";position:absolute;z-index:0;left:3%;top:35%;bottom:-25%;width:calc(var(--lvl) / 9 * 94%);background:var(--belt);border-radius:999px;filter:blur(12px);opacity:0;pointer-events:none;transition:opacity .5s var(--ease-std),transform .5s var(--ease-out)}
.belt__lvl,.belt__name{transition:color .4s var(--ease-std)}
.belt.is-picked .belt__bar{transform:translateY(-3px)}
.belt.is-picked .belt__track::after{opacity:.5;transform:translateY(3px)}
.belt.is-picked .belt__bar::before{animation:jj-dj-sheen .9s var(--ease-out)}
.belt.is-picked .belt__lvl{color:var(--ink)}
@media(hover:hover){
  .belt:hover .belt__bar{transform:translateY(-3px)}
  .belt:hover .belt__track::after{opacity:.5;transform:translateY(3px)}
  .belt:hover .belt__bar::before{animation:jj-dj-sheen .9s var(--ease-out)}
  .belt:hover .belt__lvl{color:var(--ink)}
}
/* the ladder (.is-ladder): a pencil outline of every belt; each one paints in, left to right, as you pass it (.is-earned),
   and the one you have just earned stays lifted (.is-current). Belts earned in the same frame follow each other (--k). */
.belts.is-ladder .belt__track::before{content:"";position:absolute;left:0;top:0;bottom:0;width:calc(var(--lvl) / 9 * 100%);border-radius:2px;box-shadow:inset 0 0 0 1px var(--hair);transition:opacity .3s var(--ease-std) .4s}
.belts.is-ladder .belt.is-earned .belt__track::before,.belts.is-ladder .belt.is-picked .belt__track::before{opacity:0}
@media(hover:hover){.belts.is-ladder .belt:hover .belt__track::before{opacity:0}}
.belts.is-ladder .belt__bar{-webkit-mask:linear-gradient(90deg,#000 48%,transparent 52%) 100% 0/220% 100% no-repeat;mask:linear-gradient(90deg,#000 48%,transparent 52%) 100% 0/220% 100% no-repeat;
  transition:-webkit-mask-position 1s var(--ease-out) calc(var(--k,0) * 80ms),mask-position 1s var(--ease-out) calc(var(--k,0) * 80ms),transform .5s var(--ease-out)}
.belts.is-ladder .belt.is-earned .belt__bar,.belts.is-ladder .belt.is-picked .belt__bar{-webkit-mask-position:0 0;mask-position:0 0}
@media(hover:hover){.belts.is-ladder .belt:hover .belt__bar{-webkit-mask-position:0 0;mask-position:0 0}}
.belts.is-ladder .belt__name{color:var(--muted)}
.belts.is-ladder .belt.is-earned .belt__name,.belts.is-ladder .belt.is-picked .belt__name{color:var(--ink)}
.belts.is-ladder .belt.is-current .belt__bar{transform:translateY(-2px)}
.belts.is-ladder .belt.is-current .belt__track::after{opacity:.38;transform:translateY(2px);transition-delay:.25s}
.belts.is-ladder .belt.is-current .belt__lvl{color:var(--ink)}
/* one belt lifted at a time: the one you point at or tap sets the current one down */
@media(hover:hover){.belts:hover .belt.is-current:not(:hover) .belt__track::after{opacity:0;transition-delay:0s}.belts:hover .belt.is-current:not(:hover) .belt__bar{transform:none}}
.belts.has-pick .belt.is-current:not(.is-picked) .belt__track::after{opacity:0;transition-delay:0s}
.belts.has-pick .belt.is-current:not(.is-picked) .belt__bar{transform:none}

/* the four tiles: the rules draw in order (.is-ink → .is-drawn); the tile you point at, tap, or (phones) read at the
   reading line is in ink: its rule doubles, its number and its line darken */
.tile__n,.tile__p{transition:color .4s var(--ease-std)}
.tiles.is-ink .tile{position:relative;border-top-color:transparent;-webkit-tap-highlight-color:transparent}
.tiles.is-ink .tile::before{content:"";position:absolute;left:0;right:0;top:-1.5px;height:1.5px;background:var(--ink);transform-origin:0 0;scale:0 1;
  transition:scale .9s var(--ease-out) calc(.1s + var(--i,0) * .14s),transform .45s var(--ease-out)}
.tiles.is-ink.is-drawn .tile::before{scale:1 1}
.tiles.is-ink .tile.is-current::before,.tiles.is-ink .tile.is-picked::before{transform:scaleY(2.4)}
.tile.is-current .tile__n,.tile.is-current .tile__p,.tile.is-picked .tile__n,.tile.is-picked .tile__p{color:var(--ink)}
@media(hover:hover){
  .tiles.is-ink .tile:hover::before{transform:scaleY(2.4)}
  .tile:hover .tile__n,.tile:hover .tile__p{color:var(--ink)}
}

/* Join, without the photos: one spacing step after the tiles, signed with a brush stroke instead of a rule */
.inside+.join{padding-top:0}
.join__in{position:relative;border-top-color:transparent}
.join__in::before,.thanks__t::after{content:"";position:absolute;pointer-events:none;background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 240' preserveAspectRatio='none'%3E%3Cpath fill='%23111' d='M2 90L5 71L10 52L17 36L26 24L32 21L62 21L92 22L122 23L152 24L182 26L212 27L242 28L272 29L302 30L332 31L362 32L392 33L422 35L452 36L482 37L512 38L542 39L572 39L602 40L632 41L662 42L692 52L692 59L662 68L632 67L602 67L572 66L542 66L512 65L482 65L452 64L422 64L392 63L362 62L332 62L302 61L272 60L242 59L212 59L182 58L152 57L122 56L92 55L62 55L32 54L26 57L17 64L10 76L5 89L2 101ZM2 97L5 83L10 67L17 55L26 45L32 43L62 43L92 44L122 45L152 46L182 47L212 48L242 48L272 49L302 50L332 51L362 52L392 53L422 54L452 54L482 55L512 56L542 56L572 57L602 58L632 58L662 59L692 59L722 60L752 60L782 61L812 61L842 62L872 62L902 71L902 76L872 84L842 85L812 85L782 85L752 85L722 85L692 85L662 84L632 84L602 84L572 84L542 84L512 84L482 83L452 83L422 83L392 82L362 82L332 81L302 81L272 80L242 80L212 79L182 79L152 78L122 78L92 77L62 76L32 76L26 78L17 83L10 91L5 100L2 108ZM2 105L5 94L10 83L17 73L26 66L32 65L62 65L92 65L122 66L152 67L182 68L212 68L242 69L272 70L302 70L332 71L362 71L392 72L422 73L452 73L482 73L512 74L542 74L572 85L572 92L542 102L512 102L482 102L452 102L422 102L392 102L362 101L332 101L302 101L272 101L242 100L212 100L182 100L152 99L122 99L92 99L62 98L32 98L26 99L17 102L10 106L5 111L2 116ZM662 85L692 76L722 76L752 76L782 76L812 76L842 77L872 77L902 77L932 77L962 77L992 85L992 90L962 98L932 98L902 99L872 99L842 99L812 100L782 100L752 100L722 101L692 101L662 92ZM2 112L5 105L10 98L17 92L26 88L32 86L62 87L92 87L122 88L152 88L182 89L212 89L242 90L272 90L302 90L332 91L362 91L392 91L422 92L452 92L482 92L512 92L542 92L572 92L602 92L632 92L662 92L692 92L722 92L752 92L782 92L812 92L842 91L872 91L902 91L932 91L962 91L992 90L1022 90L1052 90L1082 97L1082 102L1052 109L1022 110L992 111L962 111L932 112L902 113L872 114L842 114L812 115L782 116L752 116L722 117L692 117L662 118L632 118L602 119L572 119L542 120L512 120L482 120L452 120L422 121L392 121L362 121L332 121L302 121L272 121L242 121L212 121L182 121L152 121L122 120L92 120L62 120L32 120L26 120L17 120L10 121L5 122L2 123ZM2 119L5 116L10 113L17 110L26 109L32 108L62 108L92 109L122 109L152 109L182 110L212 110L242 110L272 110L302 110L332 111L362 111L392 111L422 111L452 111L482 110L512 110L542 110L572 110L602 110L632 109L662 109L692 109L722 108L752 108L782 107L812 107L842 106L872 106L902 105L932 105L962 104L992 104L1022 103L1052 103L1082 102L1112 102L1142 101L1172 107L1172 111L1142 119L1112 120L1082 121L1052 122L1022 123L992 124L962 125L932 126L902 127L872 128L842 129L812 130L782 131L752 132L722 133L692 134L662 135L632 135L602 136L572 137L542 138L512 138L482 139L452 139L422 140L392 140L362 141L332 141L302 141L272 141L242 142L212 142L182 142L152 142L122 142L92 142L62 142L32 142L26 141L17 139L10 136L5 133L2 130ZM2 126L5 127L10 128L17 129L26 130L32 130L62 130L92 130L122 130L152 131L182 131L212 131L242 131L272 131L302 130L332 130L362 130L392 130L422 130L452 129L482 129L512 128L542 128L572 127L602 127L632 126L662 126L692 125L722 124L752 124L782 123L812 122L842 130L842 135L812 145L782 147L752 148L722 149L692 150L662 151L632 152L602 153L572 154L542 155L512 156L482 157L452 158L422 159L392 159L362 160L332 161L302 161L272 162L242 162L212 163L182 163L152 163L122 163L92 164L62 164L32 163L26 162L17 158L10 151L5 144L2 137ZM932 127L962 118L992 125L992 130L962 139L932 132ZM1052 122L1082 114L1112 113L1142 113L1172 118L1172 123L1142 130L1112 132L1082 133L1052 127ZM2 133L5 138L10 143L17 148L26 151L32 152L62 152L92 152L122 152L152 152L182 152L212 151L242 151L272 151L302 151L332 150L362 150L392 149L422 149L452 148L482 147L512 147L542 146L572 145L602 144L632 143L662 142L692 141L722 150L722 156L692 167L662 168L632 169L602 171L572 172L542 173L512 175L482 176L452 177L422 178L392 179L362 180L332 181L302 181L272 182L242 183L212 183L182 184L152 184L122 185L92 185L62 185L32 185L26 183L17 176L10 167L5 155L2 144ZM2 141L5 149L10 159L17 166L26 172L32 174L62 174L92 174L122 173L152 173L182 173L212 172L242 172L272 171L302 171L332 170L362 169L392 168L422 168L452 167L482 166L512 165L542 164L572 163L602 172L602 178L572 190L542 191L512 193L482 194L452 195L422 197L392 198L362 199L332 200L302 201L272 202L242 203L212 204L182 205L152 206L122 206L92 207L62 207L32 207L26 204L17 195L10 182L5 167L2 152ZM692 167L722 157L752 155L782 163L782 169L752 179L722 181L692 174ZM2 148L5 161L10 174L17 185L26 193L32 195L62 196L92 195L122 195L152 194L182 194L212 193L242 192L272 192L302 191L332 190L362 189L392 188L422 187L452 186L482 184L512 183L542 182L572 190L572 197L542 209L512 211L482 213L452 214L422 216L392 217L362 219L332 220L302 221L272 223L242 224L212 225L182 226L152 227L122 228L92 228L62 229L32 229L26 225L17 213L10 197L5 178L2 159ZM632 187L662 176L692 174L722 182L722 188L692 199L662 201L632 194ZM812 176L842 174L842 180L812 182Z'/%3E%3C/svg%3E") 0 0/100% 100% no-repeat}
.join__in::before{left:0;right:0;top:-8.5px;height:16px}
@media(max-width:599px){.join__in::before{top:-6px;height:11px}}
/* .is-ink → .is-in: the stroke is painted left to right, then the price inks in behind a soft edge, the note settles,
   and the button answers once */
.join.is-ink .join__in::before,.join.is-ink .join__price{-webkit-mask:linear-gradient(90deg,#000 45%,transparent 55%) 100% 0/220% 100% no-repeat;mask:linear-gradient(90deg,#000 45%,transparent 55%) 100% 0/220% 100% no-repeat}
.join.is-ink .join__in::before{transition:-webkit-mask-position 1.1s cubic-bezier(.55,0,.25,1),mask-position 1.1s cubic-bezier(.55,0,.25,1)}
.join.is-ink .join__price{transition:-webkit-mask-position 1s var(--ease-out) .5s,mask-position 1s var(--ease-out) .5s}
.join.is-ink .join__note{opacity:0;translate:0 8px;transition:opacity .6s var(--ease-std) 1s,translate .8s var(--ease-out) 1s}
.join.is-ink.is-in .join__in::before,.join.is-ink.is-in .join__price{-webkit-mask-position:0 0;mask-position:0 0}
.join.is-ink.is-in .join__note{opacity:1;translate:none}
.join.is-ink.is-in .join__in .cta{animation:jj-dj-ring 1.1s var(--ease-out) 1.35s}
.join .cta{transition:background-color .25s var(--ease-std),color .25s var(--ease-std),border-color .25s var(--ease-std),transform .12s var(--ease-std),translate .35s var(--ease-out),box-shadow .35s var(--ease-out)}
@media(hover:hover){.join .cta--solid:hover{translate:0 -2px;box-shadow:0 14px 28px -14px rgba(17,17,17,.55)}}
.join .cta--solid:active{translate:none;box-shadow:none}

/* thanks.html, no logo (the nav has the mark): 自由術 inks in, the brush stroke from Join paints under "It's done."
   and the heading settles onto it. Pure CSS from first paint, so the stroke is simply there without JS or with reduced motion */
.thanks__t{position:relative;width:fit-content;max-width:100%}
.thanks__t::after{left:-.02em;right:-.06em;top:calc(100% + .06em);height:clamp(9px,.13em,16px)}
.thanks__in .thanks__p{margin-top:calc(16px + .9rem)}
.thanks .kanji-eyebrow{width:fit-content}
@media(prefers-reduced-motion:no-preference){
  html.js .thanks .kanji-eyebrow,html.js .thanks__t::after{-webkit-mask:linear-gradient(90deg,#000 45%,transparent 55%) 100% 0/220% 100% no-repeat;mask:linear-gradient(90deg,#000 45%,transparent 55%) 100% 0/220% 100% no-repeat}
  html.js .thanks .kanji-eyebrow{animation:jj-dj-wipe .9s var(--ease-out) .1s both}
  html.js .thanks__t{animation:jj-dj-settle .8s var(--ease-out) .25s both}
  html.js .thanks__t::after{animation:jj-dj-wipe 1.1s cubic-bezier(.55,0,.25,1) .7s both}
}

/* the footer, every page: the links underline in ink from the left (hover, focus, a press); the eye mark blinks when
   you point at it or press it, and once as it comes into view on pages that run jj-dojo-page.js (.ftr.is-seen) */
.ftr__nav a{position:relative;justify-self:start}
.ftr__nav a::after{content:"";position:absolute;left:0;right:0;bottom:7px;height:1.5px;background:currentColor;scale:0 1;transform-origin:100% 50%;transition:scale .45s var(--ease-out)}
.ftr .ftr__nav a:hover{color:var(--ink)}
.ftr__nav a:focus-visible::after,.ftr__nav a:active::after{scale:1 1;transform-origin:0 50%}
@media(hover:hover){.ftr__nav a:hover::after{scale:1 1;transform-origin:0 50%}}
.ftr__brand .mark{transform-origin:50% 56%}
@media(prefers-reduced-motion:no-preference){
  .ftr__brand:active .mark,.ftr.is-seen .ftr__brand .mark{animation:jj-dj-blink .42s var(--ease-std)}
  @media(hover:hover){.ftr__brand:hover .mark{animation:jj-dj-blink .42s var(--ease-std)}}
}
/* ===== DOJO MOTION (v4) — end ===== */

/* ---------- about.html ---------- */
/* About hero: 自由術 in ink instead of a photo (shown once the kanji font is in; see the inline jjKanji script) */
.about-kanji{display:grid;grid-template-columns:repeat(2,1em);grid-template-rows:repeat(2,1em);justify-self:start;margin:4px var(--page-x) 40px;font-family:var(--jp);font-weight:900;font-size:min(34vw,220px);line-height:1;color:var(--ink);user-select:none}
.about-kanji .kj{display:block;height:1em;text-align:center}
.about-kanji .kj:nth-child(1){grid-area:1/1}
.about-kanji .kj:nth-child(2){grid-area:1/2}
.about-kanji .kj:nth-child(3){grid-area:2/2}
html.js:not(.kanji-ready) .about-kanji{visibility:hidden}
@media(min-width:960px){.about-kanji{justify-self:end;align-self:center;margin:0;font-size:min(calc((66svh - var(--nav-h) - 72px) / 2),20vw,250px)}}
.about-hero .hero__title{font-family:var(--font-head);font-weight:700;font-size:var(--fs-display);line-height:.95;letter-spacing:-.035em;text-wrap:balance}
.origin__grid{display:grid;grid-template-columns:minmax(0,1fr);gap:32px var(--gap)}
.origin__head{display:flex;flex-direction:column;gap:16px}
.origin__prose{max-width:34em;font-size:clamp(19px,1.1rem + .5vw,24px);line-height:1.55;letter-spacing:-.005em}
.origin__prose p{margin:0}
.origin__prose p+p{margin-top:1.1em}
.origin__more{margin-top:48px;padding-top:24px;border-top:1px solid var(--hair);display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:16px 32px}
.origin__more p{margin:0;font-size:var(--fs-lead);color:var(--muted)}
@media(min-width:960px){
  .origin__grid{grid-template-columns:repeat(12,minmax(0,1fr))}
  .origin__head{grid-column:1/6;position:sticky;top:calc(var(--nav-h) + 32px);align-self:start}
  .origin__body{grid-column:7/13}
}
.pillars{list-style:none;margin:0;padding:0}
.pillar{display:grid;grid-template-columns:minmax(0,1fr);gap:8px 32px;padding:28px 0;border-top:1px solid var(--hair)}
.pillar__num{display:flex;gap:16px;align-items:baseline;font-size:12px;font-weight:500;letter-spacing:.08em;color:var(--muted)}
.pillar__kanji{font-family:var(--jp);font-size:14px;letter-spacing:.2em}
.pillar__name{margin:0;font-family:var(--font-head);font-weight:600;font-size:var(--fs-h3);line-height:1.15;letter-spacing:-.02em}
.pillar__line{margin:0;font-size:var(--fs-lead);line-height:1.45;color:var(--muted)}
@media(min-width:960px){.pillar{grid-template-columns:repeat(12,minmax(0,1fr));align-items:baseline;padding:36px 0}.pillar__num{grid-column:1/4}.pillar__name{grid-column:4/8}.pillar__line{grid-column:8/13}}
.closing{padding-block:var(--section-y)}
.section+.closing{padding-top:0}
.closing__in{display:flex;flex-direction:column;align-items:flex-start;gap:40px;padding-top:clamp(32px,4vw,48px);border-top:1.5px solid var(--ink)}
.closing .h2{max-width:16ch}

/* ===== ABOUT MOTION (v4) — begin ===== */
/* About comes alive (jj-about.js). Every class below except the kanji soak is set by that script, so without it
   (or with JS off) the page is the static one above. Reduced motion: the script never runs and the soak is off. */

/* hero: each character soaks in from the top through the ragged ink edge of the home print (img/ink-bleed).
   Own keyframes (jj-ink-down is defined twice in this file and the later one animates the home print's mask).
   The mask lives only in the keyframes, filled backwards: once it has played (or if the mask image never loads
   and the run ends) the kanji stand unmasked */
@keyframes jj-ab-soak{
  from{-webkit-mask-image:url(img/ink-bleed-2026-11.webp);mask-image:url(img/ink-bleed-2026-11.webp);-webkit-mask-size:100% 300%;mask-size:100% 300%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:0 86%;mask-position:0 86%}
  to{-webkit-mask-image:url(img/ink-bleed-2026-11.webp);mask-image:url(img/ink-bleed-2026-11.webp);-webkit-mask-size:100% 300%;mask-size:100% 300%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:0 12%;mask-position:0 12%}
}
@media(prefers-reduced-motion:no-preference){
  html.js.kanji-ready .about-kanji .kj{animation:jj-ab-soak 1.25s cubic-bezier(.45,0,.25,1) backwards;animation-delay:calc(.06s + var(--k,0) * .3s)}
}
/* wet ink: where the pointer (or a finger) comes close, a soft bleed of the character spreads out towards it (--go, --gs, --gx, --gy from the script; 0 at rest) */
.about-kanji.ab-live{position:relative} /* the script measures each character inside it */
.about-kanji.ab-live .kj{position:relative;z-index:0;will-change:translate}
.about-kanji.ab-live .kj::before{content:attr(data-k);position:absolute;inset:0;z-index:-1;color:var(--ink);opacity:var(--go,0);filter:blur(9px);scale:var(--gs,1);translate:calc(var(--gx,0) * 1px) calc(var(--gy,0) * 1px);will-change:translate,scale,opacity;pointer-events:none}

/* origin: grey until the reading line reaches it, then ink (both pass AA). --p is 0..1 per sentence */
html.js .origin__prose.ab-read .ab-s{color:var(--ink);color:color-mix(in srgb,var(--ink) calc(var(--p,1) * 100%),var(--muted));transition:color .2s linear}
/* the bold line: a dry-brush wash of ink is laid behind its lower half, left to right across its lines
   (a paper-white cover slides off it). A wash, not an underline, so it never reads as a link */
@property --ab-u{syntax:"<percentage>";inherits:false;initial-value:0%}
html.js .origin__prose.ab-read strong{--ab-u:0%;
  background-image:linear-gradient(90deg,transparent calc(var(--ab-u) - 3%),var(--paper) var(--ab-u)),url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 20' preserveAspectRatio='none'%3E%3Cpath d='M3 6.5C60 3.2 170 2.4 300 3S392 4.6 397 6.8C399 10 396 13.4 392 15.6C300 17 150 17.6 40 17.2S2 16 3 12.2Z' fill='%23111' fill-opacity='.09'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-size:100% 100%,100% .62em;background-position:0 0,0 88%;transition:--ab-u 1.5s cubic-bezier(.55,0,.25,1)}
html.js .origin__prose.ab-read strong.is-inked{--ab-u:104%}
.ab-num{font-variant-numeric:tabular-nums}
html.js .ab-num.is-counting{position:relative;color:transparent}
html.js .ab-num.is-counting::after{content:attr(data-n);position:absolute;left:0;top:0;color:color-mix(in srgb,var(--ink) calc(var(--p,1) * 100%),var(--muted))}
/* desktop: under the sticky heading, a rule fills as you read */
.ab-progress{display:none}
@media(min-width:960px){html.js .ab-progress{display:block;height:1.5px;margin-top:8px;background:var(--ink);transform:scaleX(0);transform-origin:left center}}

/* the four pillars: each rule is painted as you reach it; the row on the reading line is in full ink, its kanji large behind it */
.pillars-sec{overflow-x:clip}
.pillars.ab-ladder .pillar{position:relative;isolation:isolate;cursor:default}
.pillars.ab-ladder .pillar::before{content:"";position:absolute;left:0;right:0;top:-1px;height:1px;background:var(--ink);transform:scaleX(0);transform-origin:left center;transition:transform .9s var(--ease-expr)}
.pillars.ab-ladder .pillar.is-past::before{transform:none}
.pillars.ab-ladder .pillar::after{content:attr(data-k);position:absolute;right:0;top:50%;z-index:-1;font-family:var(--jp);font-weight:400;font-size:clamp(68px,2.5rem + 5vw,128px);line-height:1;letter-spacing:.04em;white-space:nowrap;color:var(--ink);opacity:0;translate:0 -50%;pointer-events:none;
  -webkit-mask-image:url(img/ink-bleed-2026-11.webp);mask-image:url(img/ink-bleed-2026-11.webp);-webkit-mask-size:100% 300%;mask-size:100% 300%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:0 86%;mask-position:0 86%;
  transition:opacity .5s var(--ease-std),-webkit-mask-position .9s cubic-bezier(.45,0,.25,1),mask-position .9s cubic-bezier(.45,0,.25,1)}
.pillars.ab-ladder .pillar.is-on::after{opacity:.07;-webkit-mask-position:0 12%;mask-position:0 12%}
/* desktop: the big kanji grows out of the small one, on the left of its row */
@media(min-width:960px){.pillars.ab-ladder .pillar::after{right:auto;left:-.06em}}
.pillars.ab-ladder .pillar__kanji,.pillars.ab-ladder .pillar__line,.pillars.ab-ladder .pillar__num{transition:color .45s var(--ease-std)}
.pillars.ab-ladder .pillar.is-on .pillar__num,.pillars.ab-ladder .pillar.is-on .pillar__line{color:var(--ink)}

/* closing: the rule is painted across, then the map lights up from home and the arcs reach out */
.closing__in.ab-close{position:relative}
html.js .closing__in.ab-close{border-top-color:transparent}
html.js .closing__in.ab-close::before{content:"";position:absolute;left:0;right:0;top:-1.5px;height:1.5px;background:var(--ink);transform:scaleX(0);transform-origin:left center;transition:transform 1.3s var(--ease-expr)}
html.js .closing__in.ab-close.is-in::before{transform:none}
@property --ab-r{syntax:"<percentage>";inherits:true;initial-value:100%}
.ab-map{position:relative;width:100%;aspect-ratio:1000/361.1;pointer-events:none;--ab-r:100%;transition:--ab-r 2.2s cubic-bezier(.3,0,.2,1) .5s}
html.js .closing__in.ab-close:not(.is-in) .ab-map{--ab-r:0%}
.ab-map img,.ab-map svg{position:absolute;inset:0;width:100%;height:100%}
.ab-map img{opacity:.6;-webkit-mask-image:radial-gradient(circle at var(--hx,91.67%) var(--hy,85.62%),#000 var(--ab-r),transparent calc(var(--ab-r) + 12%));mask-image:radial-gradient(circle at var(--hx,91.67%) var(--hy,85.62%),#000 var(--ab-r),transparent calc(var(--ab-r) + 12%))}
.ab-map svg{overflow:visible}
.ab-map__arc{fill:none;stroke:var(--ink);stroke-opacity:.28;stroke-width:1;stroke-dasharray:1 1}
.ab-map__dot{fill:var(--ink);transform-box:fill-box;transform-origin:center}
.ab-map__ring{fill:none;stroke:var(--ink);stroke-width:1.2;opacity:0;transform-box:fill-box;transform-origin:center}
.ab-map__home{transition:opacity .4s var(--ease-std) .4s}
html.js .closing__in.ab-close:not(.is-in) .ab-map__home{opacity:0}
.closing__in.is-alive .ab-map__ring{animation:jj-ring 3.4s var(--ease-out) infinite}
.closing__in.is-paused .ab-map__ring{animation-play-state:paused}
@media(min-width:960px){
  .closing__in.ab-close .ab-map{position:absolute;right:0;bottom:4px;width:min(46%,640px)}
}
/* ===== ABOUT MOTION (v4) — end ===== */

/* ---------- next drop ---------- */
.cap{padding-block:var(--section-y);background:var(--paper)}
.cap__in{display:grid;grid-template-columns:minmax(0,1fr);gap:32px var(--gap)}
.cap__head{display:flex;flex-direction:column;gap:16px}
.cap__title{margin:0}
.cap__form{display:flex;gap:8px;width:100%}
.cap__form input{flex:1;min-width:0;height:56px;padding:0 24px;font-family:var(--sans);font-size:16px;color:var(--ink);background:var(--paper);border:1px solid var(--line-strong);border-radius:999px;transition:border-color .15s var(--ease-std),box-shadow .15s var(--ease-std)}
.cap__form input:focus{outline:none;border-color:var(--ink);box-shadow:0 0 0 1px var(--ink),0 0 0 4px rgba(17,17,17,.12)}
.cap__msg{margin:12px 0 0;min-height:1.5em;font-size:14px;font-weight:500;color:var(--ink)}
@media(max-width:599px){.cap__form{flex-direction:column}.cap__form input{flex:0 0 auto;width:100%}.cap__form .cta{width:100%}}
@media(min-width:960px){.cap__in{grid-template-columns:repeat(12,minmax(0,1fr));align-items:end}.cap__head{grid-column:1/7}.cap__body{grid-column:7/13}}

/* ---------- thanks ---------- */
.thanks{display:grid;align-items:center;min-height:calc(100svh - var(--nav-h));padding-block:var(--section-y)}
.thanks__in{max-width:680px}
.thanks__t{margin:20px 0 0}
.thanks__p{margin:16px 0 0;font-size:var(--fs-lead);color:var(--muted)}
.thanks__ctas{margin-top:40px}
.thanks__ref{margin:32px 0 0;font-size:12px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);word-break:break-all}

/* ---------- footer ---------- */
.ftr{padding:64px 0 40px;border-top:1px solid var(--hair)}
.ftr__in{display:grid;grid-template-columns:minmax(0,1fr);gap:40px var(--gap)}
.ftr__brand{display:flex;align-items:center;gap:16px}
.ftr__brand .mark{width:48px;height:48px;object-fit:contain}
.ftr__word{display:block;font-family:var(--serif);font-weight:800;font-size:20px;line-height:1.1;letter-spacing:.06em;text-transform:uppercase}
.ftr__tag{display:block;margin-top:4px;font-size:14px;color:var(--muted)}
.ftr__nav{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 24px}
.ftr__nav a{padding:10px 0;font-weight:500;transition:color .15s var(--ease-std)}
.ftr__nav a:hover{color:var(--muted)}
.ftr__copy{margin:0;padding-top:24px;border-top:1px solid var(--hair);font-size:14px;color:var(--muted)}
@media(min-width:600px){.ftr__nav{display:flex;flex-wrap:wrap;gap:0 32px}}
@media(min-width:960px){.ftr__in{grid-template-columns:repeat(12,minmax(0,1fr));align-items:center}.ftr__brand{grid-column:1/5}.ftr__nav{grid-column:5/13;justify-content:flex-end}.ftr__copy{grid-column:1/-1}}

/* ============================================================
   MOTION (preview v2) — calm, one moment per section.
   Everything here is off under prefers-reduced-motion.
   ============================================================ */

/* cross-page fades where the browser supports them */
@view-transition{navigation:auto}
.nav{view-transition-name:jj-nav}
::view-transition-old(root),::view-transition-new(root){animation-duration:.32s;animation-timing-function:var(--ease-std)}

/* ---------- the opening (M3): the mark opens the site ----------
   Pure CSS from first paint; the script in index.html <head> picks one of two classes before anything paints:
   .jj-open  first visit this session: the brush mark is painted large (an SVG mask, .op-p strokes: the brow,
             the lid and the lower sweep open the eye, then the slash cuts down), then it flies into the nav corner
             and becomes the nav logo while the H1 print paints itself in underneath: the ensō, the figure,
             the blossoms; the type and the buttons rise while it lands. 2.2s in all; the bloom is the last thing to end.
             A scroll, wheel, key or click plays the rest at speed (the script in <head>), then removes the class.
   .jj-back  every other visit (return, reload, from dojo.html, an anchor): a short entrance, under .8s.
   Neither class (no JS, reduced motion): the final state. The page underneath is real and live throughout. */
@keyframes jj-rise{from{transform:translateY(110%)}to{transform:none}}
@keyframes jj-up{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
@keyframes jj-op-last{from{opacity:0;transform:translateY(10px)}35%{opacity:1}to{opacity:1;transform:none}} /* the buttons: opaque early, a half-faded black pill reads as disabled */
@keyframes jj-fade{from{opacity:0}to{opacity:1}}
@keyframes jj-settle{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
/* the ink, in three mask layers: the ensō's ring (bottom) cut by a soft conic sweep that runs anticlockwise from
   the head of the stroke, the way it was painted; the figure then soaks down from the top through a ragged ink edge
   (img/ink-bleed-2026-11.webp, a 1.8KB mask, slid down with mask-position). Then the blossoms open out from the branch. */
@property --ink-a{syntax:"<angle>";inherits:false;initial-value:400deg}
@property --ink-p{syntax:"<percentage>";inherits:false;initial-value:16%}
@property --bloom-r{syntax:"<percentage>";inherits:false;initial-value:100%}
@keyframes jj-ink{from{--ink-a:0deg}to{--ink-a:400deg}}
@keyframes jj-ink-down{from{--ink-p:84%}to{--ink-p:16%}}
@keyframes jj-bloom{from{--bloom-r:0%;opacity:0}to{--bloom-r:100%;opacity:1}}
/* the mark: painted (stroke-dashoffset in the mask), a slow settle as if the camera eases back, a small give as the
   slash lands, then three nested moves so the flight arcs: it lifts (y) a beat before it glides (x) and shrinks (scale) */
@keyframes jj-paint{from{stroke-dashoffset:var(--s)}to{stroke-dashoffset:0}} /* --s starts each dash a cap-radius before its path */
@keyframes jj-op-settle{0%{scale:1.045}84%{scale:1.006}90%{scale:.994}100%{scale:1}}
@keyframes jj-op-y{from{translate:0 var(--op-y)}to{translate:0 0}}
@keyframes jj-op-x{from{translate:var(--op-x) 0}to{translate:0 0}}
@keyframes jj-op-s{from{scale:1}to{scale:var(--op-s)}}
@keyframes jj-op-out{to{opacity:0}}
.opening{display:none}
.hero__petals{position:absolute;inset:0;pointer-events:none}
.hero__petals i{position:absolute;left:0;top:0;width:var(--pw,22px);height:var(--pw,22px);opacity:0;background:url(img/petals-2026-11.webp) 0 0/400% 100% no-repeat;will-change:transform,opacity}
@media(prefers-reduced-motion:no-preference){
  html.js .hero--home .word+.word .ltr{--o:4}
  html.js .hero--home .wordmark .ltr:nth-child(1){--i:calc(var(--o,0) + 0)}
  html.js .hero--home .wordmark .ltr:nth-child(2){--i:calc(var(--o,0) + 1)}
  html.js .hero--home .wordmark .ltr:nth-child(3){--i:calc(var(--o,0) + 2)}
  html.js .hero--home .wordmark .ltr:nth-child(4){--i:calc(var(--o,0) + 3)}
  html.js .hero--home .wordmark .ltr:nth-child(5){--i:calc(var(--o,0) + 4)}

  /* .jj-open: the mark. It sits where the nav logo sits, at the full painted size (--op-b, set in <head>),
     and starts moved out to the middle of the screen; it lands at scale --op-s = 32px, exactly on the nav mark. */
  /* the paper: below the nav, the page waits under plain white while the mark is painted (the compact hero puts the
     apparel shelf on the first screen), then clears as the mark takes off. It takes no clicks; any input clears it fast */
  html.js.jj-open body::before{content:"";position:fixed;inset:var(--nav-h) 0 0;z-index:59;background:var(--paper);pointer-events:none;animation:jj-op-out .3s var(--ease-std) 1.14s both}
  /* 768+: the compact hero leaves "The uniform." and the tees on the first screen. Below the hero the paper holds until the
     print has painted (~1.9s), then lifts by 2.2s, so the hero arrives first. A skip fast-forwards it with the rest */
  @media(min-width:768px){html.js.jj-open body::after{content:"";position:fixed;inset:calc(var(--nav-h) + clamp(460px,calc(66svh - var(--nav-h)),600px)) 0 0;z-index:59;background:var(--paper);pointer-events:none;animation:jj-op-out .26s var(--ease-std) 1.92s both}}
  html.js.jj-open .opening{display:block;position:fixed;z-index:70;left:var(--page-x);top:calc((var(--nav-h) - 32px) / 2);width:var(--op-b);height:var(--op-b);pointer-events:none;
    --op-x:calc(50vw - var(--page-x) - var(--op-b) / 2);--op-y:calc(47svh - (var(--nav-h) - 32px) / 2 - var(--op-b) / 2);
    animation:jj-op-y .62s cubic-bezier(.55,0,.12,1) 1.12s both,jj-op-out .1s linear 1.74s both}
  html.js.jj-open .opening__x{width:100%;height:100%;animation:jj-op-x .62s cubic-bezier(.72,0,.2,1) 1.12s both}
  html.js.jj-open .opening__s{width:100%;height:100%;transform-origin:0 0;will-change:scale;animation:jj-op-s .62s cubic-bezier(.62,0,.16,1) 1.12s both}
  html.js.jj-open .opening svg{display:block;width:100%;height:100%;fill:#000;animation:jj-op-settle 1.05s cubic-bezier(.3,0,.3,1) both}
  .op-p{fill:none;stroke:#fff;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1 3;animation:jj-paint var(--d) var(--e,cubic-bezier(.55,0,.25,1)) var(--t) both}
  .op-p--1{--s:1.09;--t:0s;--d:.34s} /* the brow, left to right, from the first frame */
  .op-p--2{--s:1.24;--t:.2s;--d:.3s} /* the lid */
  .op-p--3{--s:1.19;--t:.27s;--d:.33s} /* the lower sweep */
  .op-p--4{--s:1.19;--t:.38s;--d:.24s}
  .op-p--5{--s:1.13;--t:.68s;--d:.08s;--e:cubic-bezier(.4,0,.9,.7)} /* the slash: in fast from the top... */
  .op-p--6{--s:1.06;--t:.76s;--d:.16s;--e:cubic-bezier(.2,.4,.3,1)} /* ...and out through the eye (done at .92s); a beat of .2s, then the flight */
  .op-cut{fill:none;stroke:#000} /* keep the slash above the brow and its tail below the eye hidden until it cuts; the brow and eye show whole */
  .op-flood{fill:#fff;animation:jj-fade .08s linear .9s both}

  /* .jj-open: only the logo hands over (its own mark appears the frame the flying one lands on it); the menu and the bag are there from frame 1 */
  html.js.jj-open .nav__brand .mark{animation:jj-fade .01s linear 1.73s both}

  /* .jj-open: the print paints itself in once the mark has cleared the stage (later on phones, where it flies across the print) */
  html.js.jj-open .hero--home{--t-enso:1.22s;--d-enso:.86s;--t-fig:1.32s;--d-fig:.8s;--t-bloom:1.68s;--d-bloom:.52s}
  html.js.jj-open .hero--home .hero__ink{
    --ink-down:url(img/ink-bleed-2026-11.webp);
    --ink-sweep:conic-gradient(from 18deg at 47% 32%,transparent calc(360deg - var(--ink-a)),#000 calc(400deg - var(--ink-a)));
    --ink-ring:radial-gradient(circle at 47% 32%,transparent 17%,#000 22%,#000 41%,transparent 47%);
    -webkit-mask-image:var(--ink-down),var(--ink-sweep),var(--ink-ring);-webkit-mask-composite:source-over,source-in;
    mask-image:var(--ink-down),var(--ink-sweep),var(--ink-ring);mask-composite:add,intersect;
    -webkit-mask-size:100% 300%,100% 100%,100% 100%;mask-size:100% 300%,100% 100%,100% 100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
    -webkit-mask-position:0 var(--ink-p),0 0,0 0;mask-position:0 var(--ink-p),0 0,0 0;
    animation:jj-ink var(--d-enso) cubic-bezier(.45,0,.2,1) var(--t-enso) both,jj-ink-down var(--d-fig) cubic-bezier(.4,0,.2,1) var(--t-fig) both}
  html.js.jj-open .hero--home .hero__bloom{-webkit-mask-image:radial-gradient(ellipse at 70% 24%,#000 var(--bloom-r),transparent calc(var(--bloom-r) + 18%));mask-image:radial-gradient(ellipse at 70% 24%,#000 var(--bloom-r),transparent calc(var(--bloom-r) + 18%));animation:jj-bloom var(--d-bloom) var(--ease-out) var(--t-bloom) both}
  html.js.jj-open .hero--home .hero__eyebrow{animation:jj-up .5s var(--ease-out) 1.2s both}
  html.js.jj-open .hero--home .wordmark .ltr{animation:jj-rise .52s var(--ease-out) both;animation-delay:calc(1.24s + var(--i,0) * .022s)}
  html.js.jj-open .hero--home .hero__tag{animation:jj-up .48s var(--ease-out) 1.36s both}
  html.js.jj-open .hero--home .hero__ctas{animation:jj-op-last .46s var(--ease-out) 1.45s both} /* solid by ~1.6s */
  @media(max-width:959px){html.js.jj-open .hero--home{--t-enso:1.34s;--d-enso:.78s;--t-fig:1.42s;--d-fig:.74s;--t-bloom:1.72s;--d-bloom:.48s}} /* the bloom ends at 2.2s here too */

  /* .jj-back: the short entrance */
  html.js.jj-back .hero--home .hero__ink{animation:jj-settle .7s var(--ease-out) both}
  html.js.jj-back .hero--home .hero__bloom{animation:jj-fade .6s var(--ease-out) .16s both}
  html.js.jj-back .hero--home .hero__eyebrow{animation:jj-up .5s var(--ease-out) .04s both}
  html.js.jj-back .hero--home .wordmark .ltr{animation:jj-rise .55s var(--ease-out) both;animation-delay:calc(.04s + var(--i,0) * .02s)}
  html.js.jj-back .hero--home .hero__tag{animation:jj-up .5s var(--ease-out) .16s both}
  html.js.jj-back .hero--home .hero__ctas{animation:jj-up .5s var(--ease-out) .22s both}
}

/* product media: swipe to the flat art on touch screens */
.pcard__dots{display:none}
@media(hover:none){
  .pcard--swap .pcard__media{display:flex;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;scrollbar-width:none;overscroll-behavior-x:contain}
  .pcard--swap .pcard__media::-webkit-scrollbar{display:none}
  .pcard--swap .pcard__photo,.pcard--swap .pcard__flat{position:relative;inset:auto;flex:0 0 100%;width:100%;height:100%;opacity:1;scroll-snap-align:start;scroll-snap-stop:always}
  .pcard--swap .pcard__flat{background:var(--surface)}
  .pcard__dots{position:relative;z-index:1;display:flex;justify-content:center;gap:6px;height:0;pointer-events:none}
  .pcard__dots i{width:6px;height:6px;margin-top:-18px;border-radius:50%;background:rgba(255,255,255,.45);box-shadow:0 0 0 1px rgba(17,17,17,.35);transition:background-color .2s var(--ease-std)}
  .pcard__dots i.is-on{background:#fff;box-shadow:0 0 0 1px rgba(17,17,17,.6)}
}

/* add to cart: a crisp press, then the bag answers when the drawer closes */
@keyframes jj-press{0%{transform:scale(1);box-shadow:0 0 0 0 rgba(17,17,17,.28)}30%{transform:scale(.965)}100%{transform:scale(1);box-shadow:0 0 0 12px rgba(17,17,17,0)}}
.cta.is-added{animation:jj-press .55s var(--ease-out)}
@keyframes jj-bag{0%{transform:none}35%{transform:translateY(-3px) scale(1.12)}70%{transform:translateY(0) scale(.96)}100%{transform:none}}
@keyframes jj-pop{0%{transform:scale(.4)}60%{transform:scale(1.25)}100%{transform:scale(1)}}
.cartbtn.is-bump svg{animation:jj-bag .6s var(--ease-out)}
.cartbtn.is-bump .cartbtn__n{animation:jj-pop .5s var(--ease-out) .08s both}

/* the fighter card: a collectible that answers the pointer */
/* perspective lives on .forge__dock (a perspective on the well would trap the docked card) */
.fc{transform:rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));transform-style:preserve-3d;transition:background .5s ease,transform .7s var(--ease-out);will-change:transform;touch-action:pan-y}
.fc.is-live{transition:background .5s ease,transform .12s linear}
.fc::after{content:"";position:absolute;inset:0;z-index:3;pointer-events:none;opacity:var(--sheen,0);transition:opacity .45s var(--ease-std);mix-blend-mode:screen;
  background:
    radial-gradient(circle at var(--mx,50%) var(--my,30%),rgba(255,255,255,.3) 0,rgba(255,255,255,.08) 22%,transparent 46%),
    linear-gradient(118deg,transparent 18%,rgba(255,140,220,.1) 32%,rgba(140,220,255,.12) 44%,rgba(255,240,150,.1) 56%,transparent 70%) var(--sx,50%) var(--sy,50%)/260% 260% no-repeat}
@keyframes jj-bump{0%{scale:1}35%{scale:.975}100%{scale:1}}
.fc.is-bump{animation:jj-bump .38s var(--ease-out)}

/* the Dojo map comes alive (jj-dojo-map.js) */
.dmap__region .dmap__halo,.dmap__region .dmap__dot,.dmap__region .dmap__ring{transform-box:fill-box;transform-origin:center}
.dmap__trav{fill:var(--ink)}
@keyframes jj-breathe{0%,100%{transform:scale(1);fill-opacity:.1}50%{transform:scale(1.4);fill-opacity:.035}}
@keyframes jj-ring{0%{transform:scale(.7);opacity:.7}100%{transform:scale(2.6);opacity:0}}
.dmap.is-alive .dmap__halo{animation:jj-breathe 5.2s ease-in-out infinite;animation-delay:var(--d,0s)}
.dmap.is-alive .is-home .dmap__ring{animation:jj-ring 3.4s var(--ease-out) infinite}
.dmap.is-paused .dmap__halo,.dmap.is-paused .dmap__ring{animation-play-state:paused}
.dmap__region .dmap__dot{transition:transform .3s var(--ease-out)}
.dmap__region.is-hot .dmap__dot{transform:scale(1.3)}
.dmap.has-focus .dmap__region:not(.is-hot) .dmap__dot{opacity:.55}
.dmap.has-focus .dmap__node:not(.is-hot) .dmap__n{opacity:.5}
.dmap__n{transition:opacity .25s var(--ease-std)}

/* ---------- reveal ---------- */
html.js:not(.jj-static) [data-reveal]{opacity:0;transform:translateY(24px)}
html.jj-static [data-reveal]{transition:opacity .6s var(--ease-std),transform .6s var(--ease-out)} /* the CDN never came: settle into place */

@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
  html.js [data-reveal]{opacity:1!important;transform:none!important}
  html.js .hero--home .wordmark .ltr{opacity:1!important;transform:none!important}
  html.js .hero--home .hero__eyebrow,html.js .hero--home .hero__tag,html.js .hero--home .hero__ctas{opacity:1!important}
}
