/* John & Julius Salong, the home page as living scenes — shared materials. Forked 27 Sep 2026 from The Human Signal v4
   (workstreams/the-manual/human-signal-v4/core.css). Every scene sits on its own designed surface; no photographs of
   floors, fabric or wood as backgrounds (the one textile on the page is a real artwork, Staden I–III, drawn as cloth). */
@font-face { font-family: 'Kerub'; src: url('fonts/Kerub-Beta02Regular.woff2') format('woff2'); font-display: block; }
@font-face { font-family: 'Calibre'; src: url('fonts/calibre-regular.woff2') format('woff2'); font-display: block; }
@font-face { font-family: 'Hand'; src: url('fonts/caveat.woff2') format('woff2'); font-weight: 400 700; font-display: block; }
:root { --ink: #2F2F2F; --paper: #EBEBD6; --card: #F6F3E6; --sheet: #FBFAF4; --pencil: #6a6a66;
  --blue: #1f4f8a; --sky: #5AA1D8; --sun: #FCC978; --brain: #F4A6A0; --brain-text: #9C2E30; --green: #8BA36D;
  --rust: #a4462e;
  /* one colour per offer, everywhere on the page: the dyes of Staden I–III (sampled from cut/staden-{a,b,c}.webp):
     I The AI Workshop (The Portal), II The AI Masterclass (The Human Signal), III The Keynote (John, 27 Sep 2026) */
  --dye-1: #e68e6e; --dye-2: #d6c050; --dye-3: #7fa3c8; }
* { box-sizing: border-box; margin: 0; }
html { scroll-behavior: smooth; }
body { background: var(--paper); color: var(--ink); font-family: 'Calibre', system-ui, sans-serif; overflow-x: clip; -webkit-font-smoothing: antialiased; }
button { font: inherit; color: inherit; }

.grain { transition: opacity .6s ease; }
body.hero-in .grain { opacity: .1; }
.grain { position: fixed; inset: 0; width: 100vw; height: 100vh; pointer-events: none; mix-blend-mode: multiply; opacity: .34; z-index: 90; }

/* the nav: the J&JS tag, the three experiences, and one pill */
nav { position: fixed; top: 0; left: 0; right: 0; z-index: 80; display: flex; justify-content: space-between; align-items: flex-start; padding: 14px 22px; pointer-events: none; }
nav .tag { pointer-events: auto; background: var(--card); padding: 8px 12px 6px; box-shadow: 0 8px 14px -8px rgba(0,0,0,.4); transform: rotate(-2deg); }
nav .tag img { height: 24px; width: auto; display: block; }
nav .right { display: flex; align-items: center; gap: 26px; pointer-events: auto; }
nav .links { display: flex; gap: 22px; font-size: 15px; }
nav .links a { color: var(--ink); text-decoration: none; opacity: .78; transition: opacity .25s, color .35s; padding: 10px 0 8px; }
nav .links { transition: opacity .5s ease; } body.hero-in nav .links { opacity: 0; pointer-events: none; }
/* the hero carries its own two buttons; the pill would sit on Staden III's cloth (round 4), so it waits for the scroll */
body.hero-in nav a.pill { opacity: 0; pointer-events: none; visibility: hidden; transition: opacity .3s ease, visibility 0s linear .3s; }   /* (hidden, it is no Tab stop either) */
nav .links a:hover { opacity: 1; text-decoration: underline; text-decoration-color: rgba(47,47,47,.35); text-underline-offset: 6px; }
nav a.pill { font-size: 15px; padding: 10px 20px 8px; border-radius: 999px; background: var(--ink); color: var(--paper); text-decoration: none; box-shadow: 0 6px 12px -6px rgba(0,0,0,.4); white-space: nowrap; overflow: hidden; max-width: 180px;
  visibility: visible; transition: opacity .3s ease .4s, max-width .45s ease, padding .45s ease, margin .45s ease, background-color .35s, color .35s, visibility 0s; }   /* back: the room opens first, then it fades in */
/* while a scene shows its own way to reach John, the pill steps aside and gives its place to the links (no gap left):
   it fades out first, then its room closes — never a clipped sliver */
body.no-pill nav a.pill { opacity: 0; pointer-events: none; visibility: hidden; max-width: 0; padding-left: 0; padding-right: 0; margin-left: -26px;
  transition: opacity .25s ease, max-width .45s ease .25s, padding .45s ease .25s, margin .45s ease .25s, background-color .35s, color .35s, visibility 0s linear .7s; }
body.dark-nav nav a.pill { background: #EBEBD6; color: #2F2F2F; box-shadow: 0 0 0 1px rgba(40,24,24,.4), 0 6px 14px -6px rgba(0,0,0,.6); }
body.dark-nav nav .links a { color: #EBEBD6; }

/* a scene: a surface that fills the screen, and a 1600×900 stage scaled to fit it */
.scene { position: relative; height: 100vh; height: 100svh; overflow: hidden; }
.fit { position: absolute; left: 50%; top: 50%; width: 1600px; height: 900px; transform: translate(-50%, -50%) scale(var(--k, 1)); }
.vig { position: absolute; inset: 0; pointer-events: none; background: radial-gradient(ellipse at 50% 45%, transparent 55%, rgba(20,16,12,.12) 100%); }
.tooth { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; mix-blend-mode: multiply; opacity: .5; }
.a { position: absolute; }
.replay { position: absolute; right: 18px; bottom: 16px; z-index: 5; font: 13px 'Calibre'; letter-spacing: .12em; text-transform: uppercase; color: rgba(47,47,47,.7); background: rgba(246,243,230,.85); border: 1px solid rgba(47,47,47,.15); border-radius: 999px; padding: 6px 12px 4px; cursor: pointer; display: none; }
.review .replay { display: block; }
/* a scene's textures load only when it is built */
.scene:not(.built) { background-image: none !important; }

/* surfaces */
.bg-paper { background: radial-gradient(ellipse at 30% 20%, #f1efdf, #e8e5cf 70%, #e1ddc5); }
/* the room in the middle: lime-washed white brick in soft daylight (the hero draws its own room over this) */
.bg-room { background: linear-gradient(180deg, #efece4 0%, #ebe7de 70%, #cfc9be 84%, #bdb6aa 100%); }
.bg-room .tooth { opacity: .28; }
.bg-studio { background: radial-gradient(ellipse at 50% 38%, #f3efe7 0%, #e3ddd1 55%, #cfc7b8 100%); }
.bg-night { background: radial-gradient(ellipse at 50% 58%, #2e2837, #1f1a27 58%, #15111b); }
.bg-ink { background: radial-gradient(ellipse at 50% 42%, #2f2d2a, #211f1d 65%, #181716); }
.bg-desk { background: radial-gradient(ellipse at 60% 35%, #d9cfb6, #cbbfa3 65%, #bcae90); }
.bg-blush { background: radial-gradient(ellipse at 30% 25%, #f6d9d1, #eec3b9 65%, #e5b1a6); }
.bg-night .tooth, .bg-ink .tooth { mix-blend-mode: soft-light; opacity: .45; }

/* type */
.eyebrow { font-family: 'Calibre'; font-size: 14px; letter-spacing: .26em; text-transform: uppercase; color: var(--rust); }
.h1 { font-family: 'Kerub'; font-weight: normal; letter-spacing: -.012em; color: var(--ink); line-height: .98; }
.h2 { font-family: 'Kerub'; font-weight: normal; font-size: 62px; line-height: 1.02; letter-spacing: -.012em; word-spacing: .04em; color: var(--ink); }
.lead { font-family: 'Calibre'; font-size: 21px; line-height: 1.5; color: rgba(47,47,47,.8); }
.small { font-family: 'Calibre'; font-size: 15px; line-height: 1.5; color: rgba(47,47,47,.64); }
.hand { font-family: 'Hand'; font-weight: 600; color: var(--ink); }
.btn { display: inline-block; font-family: 'Calibre'; font-size: 19px; padding: 16px 30px 14px; border-radius: 999px; background: var(--ink); color: var(--paper); text-decoration: none; border: 0; cursor: pointer; }
.link { font-family: 'Calibre'; font-size: 18px; color: var(--ink); text-decoration: underline; text-decoration-color: rgba(47,47,47,.3); text-underline-offset: 6px; cursor: pointer; background: none; border: 0; }
/* a hint is pencilled on the surface itself (graphite on paper, chalk on the dark scenes): no box, no chip */
.hintnote { position: absolute; font-family: 'Hand'; font-weight: 600; font-size: 24px; line-height: 1.15; letter-spacing: .005em; color: rgba(52,51,56,.8); z-index: 30; pointer-events: none; white-space: nowrap; transform: none !important; filter: url(#graphite); }
.bg-night .hintnote, .bg-ink .hintnote { color: rgba(242,238,224,.82); filter: url(#chalk); }
.hl { display: inline-block; transform: rotate(var(--r)) translateY(var(--y)) scale(var(--s)) skewX(var(--k, 0deg)); }
.label-ex { font-family: 'Calibre'; font-size: 11px; letter-spacing: .22em; text-transform: uppercase; color: rgba(47,47,47,.5); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* the 3D pencil's invisible proxy (H.hand, pencil3d.js; from The Portal v4 with scene 03) */
.drawhand { position: absolute; left: 0; top: 0; width: 1px; height: 1px; pointer-events: none; opacity: 0; visibility: hidden; }

/* paper objects: --lift (0–1) = height above the table; the shadow grows bigger, softer and lighter */
.paper { --lift: 0; position: absolute; background: var(--card);
  box-shadow: 0 calc(10px + var(--lift) * 50px) calc(18px + var(--lift) * 40px) calc(-8px - var(--lift) * 4px) rgba(20,16,12, calc(.3 - var(--lift) * .12)), 0 1px 3px rgba(20,16,12,.14); }
.cut { position: absolute; --lift: 0; }
.cut img { display: block; width: 100%; height: auto;
  filter: drop-shadow(0 1px .6px rgba(20,16,12,.42)) drop-shadow(0 calc(4px + var(--lift) * 30px) calc(5px + var(--lift) * 22px) rgba(20,16,12,.20)) drop-shadow(0 calc(12px + var(--lift) * 46px) calc(20px + var(--lift) * 28px) rgba(20,16,12,.14)); }

/* salon tags (H.tag): a true detail on a manila tag tied to the object with cotton string */
.stag { position: absolute; left: 0; top: 0; width: 0; height: 0; z-index: 45; pointer-events: none; }
.stag .string { position: absolute; overflow: visible; }
.stag .string path { fill: none; stroke: #b7a47c; stroke-width: 1.6; stroke-linecap: round; filter: drop-shadow(0 3px 2px rgba(20,16,12,.18)); }
.stag .tagcard { position: absolute; padding: 12px 16px 13px 36px; color: #3a3530;
  background: linear-gradient(90deg, rgba(0,0,0,0) 88%, rgba(90,60,20,.10)), linear-gradient(170deg, #d9c197, #c9ae80);
  box-shadow: 0 16px 24px -10px rgba(20,16,12,.5), 0 2px 3px rgba(20,16,12,.2), inset 0 0 0 1px rgba(255,248,230,.18), inset 0 0 7px rgba(110,80,40,.28), inset -8px 0 12px -6px rgba(90,60,20,.32);
  clip-path: polygon(14px 0, 100% 0, 100% 100%, 14px 100%, 0 calc(100% - 14px), 0 14px); }
.stag .tagcard.mir { padding: 12px 36px 13px 16px; clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% calc(100% - 14px), calc(100% - 14px) 100%, 0 100%); }
.stag .tagcard.mir .eyelet { left: auto; right: 9px; }
.stag .tagcard.mir .knot { left: auto; right: 3px; transform: scaleX(-1); }
.stag .eyelet { position: absolute; left: 9px; top: 10px; width: 12px; height: 12px; border-radius: 50%; background: #3b3328; z-index: 1;
  box-shadow: 0 0 0 2.5px #c9a45c, 0 0 0 3.5px rgba(90,60,20,.45), 0 0 0 8px rgba(246,236,210,.75), 0 0 0 9px rgba(120,90,50,.18), inset 0 1px 2px rgba(0,0,0,.6); }
.stag .knot { position: absolute; left: 3px; top: 4px; width: 30px; height: 22px; overflow: visible; z-index: 2; }
.stag .knot path { fill: none; stroke: #b7a47c; stroke-width: 1.6; stroke-linecap: round; }
.stag .k { display: block; font-size: 9.5px; letter-spacing: .24em; text-transform: uppercase; color: rgba(70,52,28,.85); }
.stag b { display: block; margin-top: 4px; font-family: 'Kerub'; font-weight: normal; font-size: 23px; line-height: 1; color: #2f2b27; }
.stag p { margin-top: 6px; font-size: 13.5px; line-height: 1.38; color: rgba(47,43,39,.86); }
.stag .by { display: block; margin-top: 7px; font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: rgba(70,52,28,.8); }

/* The phone composition (APPROACH §11; ported from The Human Signal v4, 29 Sep 2026). core.js adds html.phone for phones
   either way up, an iPad upright and small windows (?phone / ?desktop force either). Each section becomes its copy
   (.pcopy), a window onto the untouched stage (.pwin, scaled by core.js so the scene's phone.crop fills the width) and
   its closing copy (.pafter), and grows with its content. */
html.phone .scene.ph { height: auto; min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; justify-content: center; }
html.phone .ph .pcopy, html.phone .ph .pafter { position: relative; z-index: 6; width: 100%; max-width: 560px; margin: 0 auto; }
html.phone .ph .pcopy { padding: 76px 24px 14px; }
html.phone .ph .pafter { padding: 10px 24px 44px; }
html.phone .ph .pcopy.empty { padding: 0; }
html.phone .ph .pafter.empty { padding: 0 0 28px; }
/* vertical swipes always scroll; sideways drags reach the scene */
html.phone .ph .pwin { position: relative; flex: none; width: 100%; z-index: 1; touch-action: pan-y; }
html.phone .ph .fit { left: 0; top: 0; transform: scale(var(--k, 1)); transform-origin: 0 0; }
html.phone .ph .pcopy > *, html.phone .ph .pafter > * { position: relative !important; inset: auto !important; width: auto !important; max-width: none !important; height: auto !important; }
html.phone .ph .pcopy > * + *, html.phone .ph .pafter > * + * { margin-top: 14px; }
/* phone type: titles in Kerub, long copy in Calibre; body at least 15 px, labels at least 12 px */
html.phone .pcopy .eyebrow, html.phone .pafter .eyebrow { font-size: 12px; letter-spacing: .22em; }
html.phone .pcopy .h1 { font-size: 46px; }
html.phone .pcopy .h2, html.phone .pafter .h2 { font-size: clamp(30px, 9.3vw, 36px) !important; line-height: 1.04; }
html.phone .pcopy .lead, html.phone .pafter .lead, html.phone .pcopy p, html.phone .pafter p { font-size: 17px; line-height: 1.5; }
html.phone .pcopy .small, html.phone .pafter .small { font-size: 14px; }
html.phone .pcopy .btn, html.phone .pafter .btn { font-size: 17px; padding: 14px 26px 12px; }
html.phone .pcopy .link, html.phone .pafter .link { font-size: 16px; }
/* hints and tags grow to stay readable in a small window (tags through GSAP, see H.tag) */
html.phone .ph .fit .hintnote { scale: var(--hz, 1); transform-origin: 0 50%; }
/* a tag's small capitals: at least ~12 px in a phone's window (the tag itself grows by --tz) */
html.phone .stag .k { font-size: 12.5px; letter-spacing: .17em; }
html.phone .stag .by { font-size: 12.5px; letter-spacing: .1em; }
html.phone nav { padding: 12px 14px; }
/* the paper's tooth and the page's fibre: small stitched tiles of the same SVG noise instead of a filter the height of
   each section (WebKit's GPU process paid for every one) */
html.phone .tooth rect, html.phone .grain rect { display: none; }
html.phone .tooth { background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='256' height='256'%3E%3Cfilter id='t' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='3' seed='21' stitchTiles='stitch' result='n'/%3E%3CfeDiffuseLighting in='n' surfaceScale='1.6' lighting-color='%23ffffff' result='l'%3E%3CfeDistantLight azimuth='225' elevation='52'/%3E%3C/feDiffuseLighting%3E%3CfeColorMatrix in='l' type='matrix' values='0.33 0.33 0.33 0 0  0.33 0.33 0.33 0 0  0.33 0.33 0.33 0 0  0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='256' height='256' filter='url(%23t)'/%3E%3C/svg%3E") 0 0 / 256px 256px repeat; }
html.phone .grain { background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='500' height='500'%3E%3Cfilter id='a' x='0' y='0'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' seed='7' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0.93  0 0 0 0 0.92  0 0 0 0 0.86  0 0 0 -1.4 1.12'/%3E%3C/filter%3E%3Crect width='500' height='500' filter='url(%23a)'/%3E%3C/svg%3E") 0 0 / 500px 500px repeat; }
/* a stage more than 0.6 of a screen away leaves the rendering: only display:none frees its memory */
html.phone .scene.ph.far > * { visibility: hidden; }
html.phone .scene.ph.far .fit, html.phone .scene.ph.far .pwin > canvas { display: none; }
html.phone *, html.phone *::before, html.phone *::after { will-change: auto !important; }
