/* ---------- tokens ---------- */
/* The slides are black and white. In colour: Khushi herself; the red (the big word on slide 1, "It's me,
   Khushi" and the arrows beside her fun facts, the hearts, her clicker and its laser); a logo or cover while
   it is hovered; a brand's page; and the wall of logos when it is shown "in colour". */
:root {
  --display: "Bodoni Moda", Didot, "Bodoni MT", "Times New Roman", serif;
  --text: Archivo, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --red: #ff1f1f;

  --gutter: clamp(20px, 5vw, 84px);
  --top: clamp(76px, 13svh, 132px); /* clears the floating nav */
  --foot: clamp(28px, 7svh, 72px);
  --ease: cubic-bezier(.2, .7, .2, 1);
  --ease-out: cubic-bezier(.23, 1, .32, 1);
  --ease-in-out: cubic-bezier(.77, 0, .175, 1);
  --spring: cubic-bezier(.3, 1.4, .5, 1);

  --fig: .3126;                 /* her standing picture: width divided by height */
  --H: min(88svh, 62vw);        /* how tall she stands on the first two slides */
  --desk: clamp(190px, 23vw, 380px); /* width kept for her picture on the slides where she sits to one side */
}
/* Slides and brand pages alternate between these two. */
[data-tone="dark"] { --bg: #000; --fg: #fff; }
[data-tone="light"] { --bg: #fff; --fg: #000; }

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  overflow: hidden;
  background: #000;
  color: #fff;
  font-family: var(--text);
  font-size: clamp(15px, .45vw + 11px, 18px);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, p, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; }
button { font: inherit; color: inherit; }
svg { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }
::selection { background: #000; color: #fff; }
[data-tone="dark"] ::selection { background: #fff; color: #000; }

.skip {
  position: fixed; left: 12px; top: 12px; z-index: 50;
  padding: .6em 1em; background: #fff; color: #000; border: 2px solid #000; font-weight: 700;
  translate: 0 -300%;
}
.skip:focus { translate: 0 0; }
.noscript { position: fixed; inset: auto 0 0 0; padding: 1em; background: #fff; color: #000; text-align: center; }

/* ---------- the sideways track ---------- */
.track {
  display: flex;
  height: 100vh; height: 100dvh;
  overflow-x: auto; overflow-y: hidden;
  overscroll-behavior: none;
  scrollbar-width: none;
}
.track::-webkit-scrollbar { display: none; }
.panel {
  position: relative; flex: 0 0 auto;
  width: 100vw; height: 100%;
  overflow: hidden auto;
  scrollbar-width: thin;
  background: var(--bg); color: var(--fg);
}
@media (pointer: coarse) {
  .track { scroll-snap-type: x proximity; }
  .panel { scroll-snap-align: start; }
}
.panel h2 {
  font-weight: 800; font-stretch: 120%;
  font-size: clamp(2.1rem, 5.4vw, 4.8rem);
  line-height: .9; letter-spacing: -.015em; text-transform: uppercase;
}
/* the heading and one line of help at the top of the social and decks slides */
.head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 1.5rem;
  padding: var(--top) var(--gutter) 0;
}
.head p { max-width: 18ch; text-align: right; text-wrap: balance; font-weight: 600; line-height: 1.25; }
.social .head p { max-width: 22ch; }

/* ---------- floating nav ---------- */
.nav {
  position: fixed; top: 14px; left: 50%; z-index: 20;
  display: flex; align-items: center; gap: 2px;
  padding: 5px; border-radius: 999px;
  background: #000; border: 1px solid rgba(255, 255, 255, .4);
  translate: -50% 0;
  transition: translate .5s var(--ease), opacity .3s, visibility 0s;
}
body[data-at="hello"] .nav {
  translate: -50% -180%; opacity: 0; visibility: hidden;
  transition: translate .5s var(--ease), opacity .3s, visibility 0s .5s;
}
.nav a {
  padding: .62em .95em; border-radius: 999px;
  color: #fff; text-decoration: none; white-space: nowrap;
  font-size: .7rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
}
.nav a:hover { background: rgba(255, 255, 255, .2); }
.nav a[aria-current="true"] { background: #fff; color: #000; }
.nav .nav__home { padding: 0; margin-right: 4px; }
.nav .nav__home:hover { background: none; }
.nav__home span { /* her face, cropped from the standing picture */
  display: block; width: 30px; height: 30px; border-radius: 50%;
  background: #fff var(--face) var(--fx) var(--fy) / var(--fz) auto no-repeat;
}

/* ---------- Khushi ---------- */
/* A .slot keeps her place on a slide. On a wide screen the picture inside it is hidden and .cast, one
   copy of her above all the slides, moves from slot to slot as the site scrolls. */
.slot { position: relative; }
.frames { position: absolute; inset: 0; } /* a pose: one picture, or two that swap in place */
.frames img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; object-position: 50% 100%; /* she always stands on the bottom edge of her space */
  opacity: 0; user-select: none; -webkit-user-select: none;
}
.frames[data-frame="0"] img:nth-child(1), .frames[data-frame="1"] img:nth-child(2) { opacity: 1; }
.pose--gap { /* a picture that has not been sent yet */
  position: absolute; inset: 0;
  display: grid; place-content: center; gap: .35em; padding: 1em;
  border: 1.5px dashed currentColor; border-radius: 14px;
  text-align: center; font-size: .8rem; line-height: 1.3; opacity: .65;
}
.pose--gap b { display: block; font-size: .66rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
.has-cast .slot > .frames, .has-cast .slot > .pose--gap { visibility: hidden; }

.cast {
  position: fixed; left: 0; top: 0; z-index: 10; width: 0; height: 0;
  pointer-events: none; will-change: transform;
}
body:not(.has-cast) .cast { display: none; }
.cast__pose { position: absolute; inset: 0; opacity: 0; color: #8d8d8d; }
/* When the page opens she pops up from below the bottom edge. */
.cast__pose, .hello .slot > .frames { transform: translateY(104%); transition: transform 1.050s var(--spring) .75s; }
.is-ready .cast__pose, .is-ready .hello .slot > .frames { transform: none; }

.slot--pop { /* slide 1: she comes up from the bottom edge, large, under the word */
  position: absolute; left: 50%; top: var(--pop); translate: -50% 0;
  height: var(--tall); width: calc(var(--tall) * var(--fig));
}
.slot--centre { /* slide 2: standing in the middle, head to toe */
  position: absolute; left: 50%; bottom: 0; translate: -50% 0;
  height: var(--H); width: calc(var(--H) * var(--fig));
}
.slot--desk { /* experience: sitting at the left with her laptop */
  position: absolute; left: var(--gutter); bottom: 0;
  width: var(--desk); height: min(58svh, 38vw);
}
.slot--kiss { /* brands: standing at the left, blowing a kiss towards the wall */
  position: absolute; left: calc(var(--gutter) + 2vw); bottom: 0;
  height: min(63svh, 42vw); aspect-ratio: .5109;
}
.slot--serious { /* "serious work": arms crossed, at the right */
  position: absolute; right: calc(var(--gutter) + 1vw); bottom: 0;
  height: min(84svh, 58vw); aspect-ratio: .3029;
}
.slot--side { /* wins: standing at the left with the trophy */
  position: absolute; left: calc(var(--gutter) + 1.5vw); bottom: 0;
  width: var(--desk); height: min(82svh, 56vw);
}
.slot--bye { /* the last slide: standing at the right */
  --h: min(70svh, 50vw);
  align-self: end; height: var(--h); width: calc(var(--h) * var(--fig));
}

/* ---------- hello ---------- */
.hello {
  overflow: hidden;
  --word: min(25vw, 37svh);                       /* the size of the word */
  --lead: max(8svh, 74px);                        /* how far down the word starts: clear of her name, which is now above its first letter */
  --pop: calc(var(--lead) + var(--word) * .845); /* where the top of her head comes to, just under the word */
  --tall: 120svh;                                 /* her full height here; the bottom edge of the screen cuts her off */
  --edge: clamp(8px, 1.5vw, 28px);                /* how close to the sides of the slide the word runs */
}
.sky { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; transition: opacity 1.8s linear; }
.hello__mark, .hello__hint {
  position: absolute; top: clamp(18px, 4svh, 34px);
  opacity: 0; transition: opacity .8s linear 1.3s;
}
.hello__mark { left: var(--gutter); }
.hello__mark h1 { font-size: .78rem; font-weight: 800; font-stretch: 112%; letter-spacing: .1em; text-transform: uppercase; }
.hello__mark p { font-size: .78rem; opacity: .8; }
.hello__hint {
  right: var(--gutter); display: flex; align-items: center; gap: .9em;
  font-size: .7rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
}
.hello__hint i {
  display: block; width: clamp(34px, 5vw, 70px); height: 1px; background: currentColor;
  transform-origin: left; animation: hint 2.6s var(--ease) infinite;
}
@keyframes hint {
  0% { transform: scaleX(0); opacity: 1; }
  55% { transform: scaleX(1); opacity: 1; }
  100% { transform: scaleX(1); opacity: 0; }
}
/* The word sits a little up the slide, and she pops up beneath it. It runs from one side of the slide to
   the other: the script counts its letters and sets --track, the space between them, so that it ends exactly
   at the right edge. --away is how far ahead of its slide it has gone as the site scrolls on (0 at a speed of 1). */
.hello__word {
  position: absolute; left: var(--edge); right: var(--edge); top: var(--lead);
  translate: calc(var(--mx, 0) * -12px - var(--away, 0px)) calc(var(--my, 0) * -7px);
  text-align: left;
  font-family: var(--display); font-weight: 700;
  font-variation-settings: "opsz" 18; /* the sturdier cut of the typeface, so the thin strokes hold up at this size */
  font-size: var(--word); line-height: .8; letter-spacing: var(--track, -.035em);
  color: var(--red); white-space: nowrap;
  transition: none; /* the spacing is measured as soon as it is set, so it must never ease into place */
}
.hello__letters { display: block; }
.hello__word .ch { /* the letters rise in one after another */
  display: inline-block; opacity: 0; translate: 0 .3em;
  transition: opacity .5s linear, translate 1s var(--spring);
  transition-delay: calc(.3s + var(--n) * .08s);
}
.hello__links {
  position: absolute; left: var(--gutter); bottom: clamp(22px, 5svh, 50px);
  display: flex; gap: 10px;
  opacity: 0; transition: opacity .8s linear 1.3s;
}
.hello__links a {
  display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .55); background: #000;
  transition: background .2s, color .2s;
}
.hello__links a:hover { background: #fff; color: #000; }
.hello__links svg { width: 20px; height: 20px; }

.is-ready .sky { opacity: 1; }
.is-ready .hello__word .ch { opacity: 1; translate: 0 0; }
.is-ready .hello__mark, .is-ready .hello__links { opacity: 1; }
.is-ready .hello__hint { opacity: .85; }

/* ---------- about and fun facts ---------- */
.about {
  display: grid; align-items: center;
  grid-template-columns: minmax(0, 1fr) calc(var(--H) * var(--fig)) minmax(0, 1fr);
  column-gap: clamp(18px, 3.2vw, 56px);
  padding: var(--top) var(--gutter) var(--foot);
  font-size: clamp(13px, min(2.35svh, 1.5vw), 23px); /* large enough that the two columns of text fill the space beside her */
}
.about__bio { grid-column: 1; justify-self: end; width: 100%; max-width: 31em; }
.about__facts { grid-column: 3; width: 100%; max-width: 31em; }
.about h2 { /* carries on the sentence that the big word started, in the same typeface and the same red */
  margin-bottom: .45em;
  font-family: var(--display); font-weight: 500; font-stretch: normal;
  font-size: clamp(2.3rem, min(5.2vw, 10svh), 5.2rem);
  line-height: .98; letter-spacing: -.02em; text-transform: none;
  color: var(--red);
}
.about__text { font-size: 1.1em; } /* three short paragraphs, set a little larger so this column stands as tall as the facts */
.about__text p + p { margin-top: .9em; }
.about__text p:first-child { font-family: var(--display); font-size: 1.32em; line-height: 1.28; }
.about__facts h3 { margin-bottom: .7em; font-size: .8em; font-weight: 800; font-stretch: 116%; letter-spacing: .08em; text-transform: uppercase; }
.about__facts li { /* a red arrow, then the fact */
  display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: .7em; align-items: start;
  padding: .6em 0 .68em; border-top: 1px solid var(--fg);
}
.about__facts svg { width: 1.3em; height: 1.3em; margin-top: .1em; color: var(--red); stroke-width: 2.2; }
.about__facts strong { display: block; font-weight: 800; }
.about__facts span { display: block; opacity: .8; }

/* ---------- experience, education, skills ---------- */
/* Two rows of three. Top row: education (above her head), experience, skills. Bottom row: her picture,
   then tools under experience and platforms under skills. Her picture is not in the grid: it keeps the
   place .slot--desk gives it, and the first column is exactly as wide as that place. */
.journey {
  --lift: clamp(70px, 10.5svh, 120px);          /* kept clear at the top, for the menu */
  --her: min(58svh, 38vw, var(--desk) * 1.37);  /* how tall her picture stands in its place */
  display: flex;
  padding: var(--lift) var(--gutter) clamp(20px, 4.5svh, 56px);
  font-size: clamp(12px, min(2.05svh, 1.3vw), 22px);
}
/* Education has only the space above her head. Under its heading (about 2.3 times the slide's type in height) the
   block is about 16.4 times as tall as its own type, so on a short, wide screen its type is set a little smaller
   than the other columns', by just enough to end above her. */
.journey__cell--edu > :not(h2) { font-size: clamp(11px, (100svh - var(--lift) - var(--her) - 2.3em) / 16.4, 1em); }
.journey__grid {
  width: 100%;
  display: grid; grid-template-columns: var(--desk) minmax(0, 1.25fr) minmax(0, .85fr); grid-template-rows: auto 1fr;
  grid-template-areas: "edu exp skills" ". tools platforms";
  column-gap: clamp(22px, 3.4vw, 60px); row-gap: clamp(14px, 3svh, 36px); align-items: start;
}
.journey__cell--edu { grid-area: edu; }
.journey__cell--exp { grid-area: exp; }
.journey__cell--skills { grid-area: skills; }
.journey__cell--tools { grid-area: tools; }
.journey__cell--platforms { grid-area: platforms; }
.journey h2 { margin-bottom: .65em; font-size: 1.42em; }
.journey__more h3 { margin-bottom: .35em; font-size: .78em; font-weight: 800; font-stretch: 116%; letter-spacing: .08em; text-transform: uppercase; }
.journey__cell > .journey__more { margin-top: 1.1em; } /* languages, under education */
.journey__list li, .journey__skills li { padding: .55em 0 .62em; border-top: 1px solid color-mix(in srgb, var(--fg) 45%, transparent); }
.journey__top { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0 1em; } /* the name, and its dates at the far end */
.journey__list h3 { font-family: var(--display); font-weight: 500; font-size: 1.5em; line-height: 1.1; }
.journey .when { font-size: .82em; font-weight: 600; opacity: .7; white-space: nowrap; }
.journey .role { font-weight: 700; }
.journey .note { margin-top: .3em; opacity: .8; }
.journey__skills strong { display: block; font-family: var(--display); font-weight: 500; font-size: 1.5em; line-height: 1.1; }
.journey__skills span { display: block; margin-top: .3em; opacity: .78; font-size: .92em; line-height: 1.38; }
/* tools and platforms: short lists, ruled like the lists above them. Tools run down two columns. */
.journey__set { display: grid; grid-auto-flow: column; grid-template-rows: repeat(var(--rows, 4), auto); grid-auto-columns: minmax(0, 1fr); column-gap: clamp(14px, 1.8vw, 30px); }
.journey__set li { padding: .4em 0 .44em; border-top: 1px solid color-mix(in srgb, var(--fg) 45%, transparent); font-weight: 700; }

/* ---------- brands: the wall of logos ---------- */
.brands {
  overflow: hidden; --side: min(31vw, 460px);
  --well: clamp(62px, 10.5svh, 96px); /* the strip at the bottom of the wall where the layout buttons sit */
}
.brands__head { position: absolute; z-index: 1; left: var(--gutter); top: var(--top); width: var(--side); }
.brands__head h2 { font-size: clamp(1.7rem, 3.5vw, 3.5rem); }
.brands__head p { margin-top: .9em; font-weight: 700; }
/* The wall is a waterfall of logos, shown one of two ways. .wall--colour sits to the right of the heading with
   every logo in colour; .wall--full fills the slide in black and white (further down). .wall--<name> says which,
   set from "view" in content.js or by the buttons below. The layouts tried before these are styled here too. */
.wall {
  --tile: min(21.5svh, 15vw); --gap: clamp(8px, 1.5svh, 15px);
  position: absolute; inset: 0 0 0 calc(var(--gutter) + var(--side) + 2vw); overflow: hidden;
}
/* The buttons for trying each one: the same black pill as the menu, under the middle of the wall. */
.views {
  position: absolute; z-index: 3; bottom: clamp(12px, 2.6svh, 26px);
  left: calc((100% + var(--gutter) + var(--side) + 2vw) / 2); translate: -50% 0;
}
/* (.pick is the same pill on the last slide, for seeing it with its sign-off and without) */
.views, .pick {
  display: flex; gap: 2px; padding: 5px; border-radius: 999px;
  background: #000; border: 1px solid rgba(255, 255, 255, .4);
}
:is(.views, .pick) button {
  appearance: none; cursor: pointer; padding: .62em .95em; border: 0; border-radius: 999px; background: none;
  color: #fff; white-space: nowrap;
  font-size: .7rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
}
:is(.views, .pick) button:hover { background: rgba(255, 255, 255, .2); }
:is(.views, .pick) button[aria-pressed="true"] { background: #fff; color: #000; }
:is(.views, .pick) button:focus-visible { outline-color: #fff; outline-offset: -4px; }

/* drift: four rows of square tiles. Odd rows drift one way, even rows the other, and the whole wall leans a little. */
.wall--drift, .wall--rings { -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 11%); mask-image: linear-gradient(90deg, transparent 0, #000 11%); }
.wall__lean {
  height: 100%;
  display: flex; flex-direction: column; justify-content: center; gap: var(--gap);
  rotate: -4deg; scale: 1.13;
}
.wall__row { display: flex; gap: var(--gap); width: max-content; }
.wall__group {
  flex: 0 0 auto; display: flex; gap: var(--gap);
  animation: wall var(--t, 80s) linear infinite; animation-play-state: paused;
}
.wall__row:nth-child(even) .wall__group { animation-direction: reverse; }
.wall.is-live .wall__group { animation-play-state: running; }
.wall.is-live:hover .wall__group { animation-play-state: paused; } /* hold still while someone is reading a logo */
@keyframes wall { to { transform: translateX(calc(-100% - var(--gap))); } }

/* waterfall: columns of tiles running up and down a floor that tilts away, fading out with distance */
.wall--fall {
  --tile: min(19svh, 13.5vw); perspective: 1500px;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 11%), linear-gradient(180deg, transparent 3%, #000 34%);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(90deg, transparent 0, #000 11%), linear-gradient(180deg, transparent 3%, #000 34%);
  mask-composite: intersect;
}
.wall__floor {
  position: absolute; left: 50%; top: 50%;
  display: flex; gap: var(--gap);
  transform: translate(-50%, -50%) rotateX(52deg) rotateZ(-34deg);
}
.wall--fall .wall__row { flex-direction: column; width: auto; translate: 0 calc(50% / var(--copies, 4)); } /* moved down half a copy, so the loop covers the floor both ways */
.wall--fall .wall__group { flex-direction: column; animation-name: wall-up; }
@keyframes wall-up { to { transform: translateY(calc(-100% - var(--gap))); } }

/* in colour: the waterfall beside the heading, with every logo in its own colours all the time */
.wall--colour .tile { filter: none; }

/* full page: the waterfall fills the slide, in black and white, and runs underneath the heading, the count
   and her picture. The heading and the count are set white on black strips so they read over moving logos. */
.wall--full {
  inset: 0;
  -webkit-mask-image: linear-gradient(180deg, transparent 2%, #000 30%);
  mask-image: linear-gradient(180deg, transparent 2%, #000 30%);
}
/* It does not stop for the pointer: the floor keeps sliding under it. The script marks the tile that is under
   the pointer at each moment (.is-lit), and that one is in colour and shows its name. The browser's own idea
   of what is hovered goes stale as the tiles slide on, so here it is not used. */
.wall--full.is-live:hover .wall__group { animation-play-state: running; }
.wall--full .tile:hover { filter: grayscale(1); }
.wall--full .tile:hover b { translate: 0 101%; }
.wall--full .tile.is-lit { filter: none; }
.wall--full .tile.is-lit b { translate: 0 0; }
.brands[data-wall="full"] .brands__head { z-index: 2; pointer-events: none; }
.brands[data-wall="full"] .brands__head span {
  padding: .1em .22em .06em; background: var(--fg); color: var(--bg);
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
}
.brands[data-wall="full"] .brands__head h2 { line-height: 1.12; }
.brands[data-wall="full"] .slot { z-index: 1; pointer-events: none; } /* she stands on the wall, not under it */
.brands[data-wall="full"] .views { left: 50%; }

/* globe: a ball of logos. The script places every tile; the ones round the back fade into the slide. */
.wall--globe { cursor: grab; user-select: none; -webkit-user-select: none; }
.wall--globe.is-held { cursor: grabbing; }
.ball { position: absolute; left: 50%; top: calc(50% + 30px - var(--well) / 2); width: 0; height: 0; } /* centred between the menu and the buttons */
.ball .tile {
  position: absolute; left: calc(var(--tile) / -2); top: calc(var(--tile) / -2);
  background: color-mix(in srgb, var(--c, #fff) calc(var(--near, 1) * 100%), var(--bg));
  border-color: color-mix(in srgb, #000 calc(var(--near, 1) * 100%), var(--bg));
}
.ball .tile img, .ball .tile em { opacity: var(--near, 1); }

/* rings: three arcs of logos turning about a point below the bottom edge. --u is the unit they are all measured in. */
.wall--rings { --tile: calc(var(--u, 100svh) * .15); }
.rings { position: absolute; left: 50%; top: calc(100% + var(--u, 100svh) * .13); width: 0; height: 0; }
.ring { position: absolute; left: 0; top: 0; width: 0; height: 0; }
.ring__spot {
  position: absolute; left: 0; top: 0; width: 0; height: 0;
  transform: rotate(var(--a)) translateY(calc(var(--u, 100svh) * var(--r) * -1));
}
.ring .tile { /* each tile turns back against its ring, so every logo stays upright */
  position: absolute; left: calc(var(--tile) / -2); top: calc(var(--tile) / -2);
  rotate: calc(var(--a) * -1);
}
.ring, .ring .tile { animation: ring var(--t, 150s) linear infinite; animation-play-state: paused; }
.ring .tile, .ring:nth-child(even) { animation-direction: reverse; }
.ring:nth-child(even) .tile { animation-direction: normal; }
.wall.is-live .ring, .wall.is-live .ring .tile { animation-play-state: running; }
.wall.is-live:hover .ring, .wall.is-live:hover .ring .tile { animation-play-state: paused; }
@keyframes ring { to { transform: rotate(1turn); } }

/* flip: twelve large tiles. Each has two faces and turns over to show the other. */
.board {
  position: absolute; inset: var(--top) clamp(16px, 4vw, 70px) var(--well);
  display: grid; grid-template-columns: repeat(var(--cols, 4), var(--tile)); gap: var(--gap);
  place-content: center; perspective: 1600px;
}
.flap {
  position: relative; width: var(--tile); height: var(--tile);
  transform-style: preserve-3d; transform: rotateX(calc(var(--turn, 0) * -180deg));
  transition: transform .9s var(--ease) var(--d, 0s);
}
.flap .tile { position: absolute; inset: 0; backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.flap .tile + .tile { transform: rotateX(180deg); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } /* for screen readers only */

/* names: every brand set in type, upright and italic by turns so one name can be told from the next */
.roll { position: absolute; inset: var(--top) calc(var(--gutter) * .8) var(--well) clamp(18px, 3.4vw, 56px); }
.roll p { font-family: var(--display); font-weight: 500; font-size: var(--fit, 1.5rem); line-height: 1.17; letter-spacing: -.012em; }
.roll span { margin-right: .28em; transition: opacity .2s linear; }
.roll span:nth-child(even) { font-style: italic; }
.roll.is-peeking span { opacity: .22; }
.roll.is-peeking span.is-on { opacity: 1; }
.roll__peek { /* the logo of the name being pointed at; it follows the pointer */
  --tile: clamp(110px, 12vw, 176px);
  position: absolute; left: 0; top: 0; z-index: 2; rotate: -3deg;
  opacity: 0; pointer-events: none; transition: opacity .15s linear, translate .12s ease-out;
}
.roll__peek.is-on { opacity: 1; }
.roll__peek .tile { display: grid; filter: none; border-width: 2px; box-shadow: 6px 6px 0 #000; }
.roll__peek .tile b { display: none; }

/* grid: every brand at once. The script grows the tiles near the pointer, like a lens. */
.wall--grid { --gap: clamp(5px, .9svh, 9px); }
.lens {
  position: absolute; inset: var(--top) clamp(40px, 4.5vw, 76px) var(--well);
  display: grid; grid-template-columns: repeat(var(--cols, 12), var(--tile)); gap: var(--gap);
  place-content: center;
}
.lens .tile { border-width: 1px; transition: filter .25s linear, scale .2s var(--ease), translate .2s var(--ease); }
.lens .tile b { font-size: .4rem; } /* the name grows with its tile, so it starts small */

.tile {
  position: relative; flex: 0 0 auto; overflow: hidden;
  width: var(--tile); height: var(--tile);
  display: grid; place-items: center;
  background: var(--c, #fff); color: var(--k, #000);
  border: 1.5px solid #000;
  filter: grayscale(1); /* black and white until hovered */
  transition: filter .25s linear;
}
.tile:hover { filter: none; }
.tile img { width: 76%; height: 60%; object-fit: contain; pointer-events: none; }
.tile img.is-edge { width: 100%; height: 100%; }
.tile img.is-fill { width: 100%; height: 100%; object-fit: cover; }
.tile b { /* the brand's name, shown while its logo is hovered */
  position: absolute; left: 0; right: 0; bottom: 0; padding: .35em .4em;
  background: #000; color: #fff; text-align: center;
  font-size: .62rem; font-weight: 700; line-height: 1.15;
  translate: 0 101%; transition: translate .2s var(--ease);
}
.tile:hover b { translate: 0 0; }
.tile--name em { /* a brand with no logo file: its name, set in type */
  padding: 0 7%; text-align: center; text-wrap: balance;
  font-family: var(--display); font-style: italic; font-weight: 500;
  font-size: calc(var(--tile) * var(--fs, .2)); line-height: 1;
}
/* small hearts flying from her open hand towards the wall, each time the kiss is sent */
.hearts { position: absolute; left: 96%; top: 15%; width: 0; height: 0; pointer-events: none; }
.hearts i { position: absolute; left: 0; top: 0; width: calc(clamp(14px, 1.6vw, 24px) * var(--s)); opacity: 0; }
.hearts svg { display: block; width: 100%; fill: var(--red); stroke: none; }
.hearts.is-off i { animation: heart 2.300s cubic-bezier(.2, .6, .3, 1) both; animation-delay: calc(var(--n) * .1s); }
@keyframes heart {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.2); }
  14% { opacity: 1; transform: translate(calc(var(--dx) * 3vw), calc(var(--dy) * -2svh)) scale(1) rotate(calc(var(--w) * -12deg)); }
  75% { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(var(--dx) * 22vw), calc(var(--dy) * -30svh + 6svh)) scale(.9) rotate(calc(var(--w) * 24deg)); }
}

/* ---------- "let's see some serious work" ---------- */
.serious { display: grid; align-content: center; padding: var(--top) var(--gutter) var(--foot); overflow: hidden; }
.serious__line {
  max-width: min(9.5em, calc(100vw - var(--gutter) * 2 - min(84svh, 58vw) * .34));
  font-family: var(--display); font-weight: 500;
  font-variation-settings: "opsz" 30; /* sturdier thin strokes, to sit with the "Hello" */
  font-size: clamp(3rem, min(11.5vw, 23svh), 13rem); line-height: .92; letter-spacing: -.03em;
}
.serious__line .w { /* each word comes into focus in turn */
  display: inline-block; opacity: 0; filter: blur(16px); translate: 0 .22em;
  transition: opacity .7s linear, filter 1s var(--ease), translate 1s var(--ease);
  transition-delay: calc(.15s + var(--n) * .13s);
}
.serious.is-seen .w { opacity: 1; filter: none; translate: 0 0; }
.serious__next {
  position: absolute; left: var(--gutter); bottom: var(--foot);
  display: grid; align-items: center; width: clamp(70px, 10vw, 150px); height: 44px;
}
.serious__next i { position: relative; display: block; height: 1.5px; background: currentColor; }
.serious__next i::after {
  content: ""; position: absolute; right: 0; top: 50%; width: 11px; height: 11px;
  border: solid currentColor; border-width: 1.5px 1.5px 0 0; translate: 0 -50%; rotate: 45deg;
}
.serious__next:hover i { scale: 1.12 1; transform-origin: left; }
.serious__next i { transition: scale .3s var(--ease); transform-origin: left; }

/* ---------- social: three cards ---------- */
.social, .decks { display: flex; flex-direction: column; }
.social__list {
  --pad: clamp(14px, 2.2vw, 36px); /* the space each side of the line between two cards */
  flex: 1 1 auto; min-height: 340px; /* on a very short screen the slide scrolls instead of squashing the cards */
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: calc(var(--pad) * 2);
  margin: clamp(10px, 3svh, 30px) var(--gutter) clamp(18px, 5svh, 48px);
}
.social__list li { position: relative; min-height: 0; }
.social__list li + li::before { content: ""; position: absolute; top: 0; bottom: 0; left: calc(var(--pad) * -1); border-left: 1px solid var(--fg); }
/* A card is three quarters reels and one quarter numbers. The three cards are the same width, so their numbers match. */
.feature {
  appearance: none; width: 100%; height: 100%; padding: 0;
  border: 0; background: none; cursor: pointer; text-align: left;
  display: grid; grid-template-rows: minmax(0, 3fr) minmax(min-content, 1fr); gap: clamp(8px, 1.8svh, 18px);
}
.feature:focus-visible { outline-offset: 6px; }
.feature__show { min-height: 0; display: grid; grid-template-rows: minmax(0, 1fr) auto; gap: clamp(6px, 1.4svh, 14px); }
/* every reel from the brand, fanned like cards in a hand; the fan opens the first time the slide is seen */
.feature__fan { position: relative; min-height: 120px; container-type: size; }
.feature__fan img {
  --ch: min(80cqh, 84cqw);             /* a card's height, and its width */
  --cw: calc(var(--ch) * .5625);
  --reach: calc((100cqw - var(--cw)) / 2 - var(--ch) * .085); /* how far the outer cards sit from the middle */
  --t: calc((var(--i) - (var(--n) - 1) / 2) / max((var(--n) - 1) / 2, .5)); /* -1 to 1 across the fan */
  --open: .86;
  position: absolute; left: 50%; top: 47%; height: var(--ch); width: var(--cw); object-fit: cover;
  border: 1.5px solid var(--fg); border-radius: clamp(8px, 1.300svh, 14px); background: var(--fg);
  filter: grayscale(1);
  transform: translate(-50%, -50%)
    translate(calc(var(--t) * var(--reach) * var(--open)), calc(var(--t) * var(--t) * 5cqh * var(--open)))
    rotate(calc(var(--t) * 9deg * var(--open)));
  transition: transform .7s var(--spring), filter .3s linear;
}
.social:not(.is-seen) .feature__fan img { --open: 0; }
.feature:hover .feature__fan img, .feature:focus-visible .feature__fan img { --open: 1; filter: none; }
.feature__text { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; column-gap: .9em; align-items: center; }
.feature__logo { --r: clamp(20px, 2vw, 29px); position: relative; grid-row: span 2; width: calc(var(--r) * 2); height: calc(var(--r) * 2); }
.feature__logo .badge__face { box-shadow: none; }
.feature:hover .badge__face, .feature:focus-visible .badge__face { filter: none; }
.feature__name { grid-column: 2; font-family: var(--display); font-style: italic; font-size: clamp(1.5rem, 2.5vw, 2.4rem); line-height: 1; }
.feature__when { /* the months the numbers cover, in brackets after the name */
  display: inline-block; vertical-align: .2em;
  font-family: var(--text); font-style: normal; font-size: max(.4em, .78rem); font-weight: 700; letter-spacing: .03em; white-space: nowrap;
}
.feature__role { grid-column: 2 / -1; margin-top: .3em; font-size: .8rem; font-weight: 600; line-height: 1.25; opacity: .8; }
.feature__go {
  grid-column: 3; grid-row: 1; align-self: center; font-size: .8rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  text-decoration: underline; text-underline-offset: .25em;
}

/* ---------- the numbers block ---------- */
/* A brand's figures, set white on black so they are the first thing read. The first figure is the largest.
   It closes each card on the social slide and opens each brand's page. */
.score {
  display: flex; flex-direction: column; justify-content: center; gap: clamp(5px, 1svh, 10px);
  padding: clamp(9px, 1.7svh, 16px) clamp(12px, 1.3vw, 20px);
  background: var(--fg, #000); color: var(--bg, #fff); text-align: left;
  container-type: inline-size; /* the figures are sized from the width of the block */
}
.score b {
  display: inline-block; font-family: var(--display); font-weight: 600; line-height: .86;
  font-variation-settings: "opsz" 30; font-variant-numeric: lining-nums; white-space: nowrap;
  transition: opacity .4s linear;
}
.score b i { /* the plus after a figure, or before it */
  margin-left: .06em; font-family: var(--text); font-style: normal; font-weight: 400; font-size: .56em; vertical-align: .42em;
}
.score b i.is-lead { margin: 0 .06em 0 0; }
.will-count:not(.is-seen) .score b { opacity: 0; }
.score__top { display: flex; align-items: baseline; gap: .5em; }
.score__top b { font-size: clamp(2.1rem, min(19cqi, 10.5svh), 7rem); letter-spacing: -.015em; }
.score__top .score__label { font-size: .95rem; font-weight: 700; line-height: 1.1; }
.score__rest {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: .5em .8em;
  padding-top: clamp(5px, 1svh, 9px); border-top: 1px solid color-mix(in srgb, var(--bg, #fff) 50%, transparent);
}
.score__rest > span { display: flex; flex-direction: column; gap: .3em; min-width: 0; }
.score__rest b { font-size: clamp(1.15rem, min(7.4cqi, 4svh), 2.4rem); }
.score__rest .score__label { font-size: .72rem; font-weight: 600; line-height: 1.15; }
@container (max-width: 250px) { /* a narrow block sets the smaller figures two to a row */
  .score__rest { grid-auto-flow: row; grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---------- decks ---------- */
/* The decks are dealt out as playing cards (.table). With deckTable.cards off in content.js they are square
   logo tiles that can be picked up and thrown (.badge) instead. */
.arena {
  position: relative; flex: 1 1 auto; min-height: 0;
  margin: clamp(10px, 3svh, 30px) var(--gutter) clamp(14px, 4svh, 40px);
}
.table { perspective: 1500px; }
.card {
  position: absolute; left: 0; top: 0; width: var(--cw, 110px); height: var(--ch, 154px); padding: 0; border: 0; background: none; cursor: pointer;
  --r: calc(var(--cw, 110px) * .39); /* sizes a brand name set in type */
  transition: transform .62s var(--ease-out); transition-delay: calc(var(--n) * 70ms);
}
.card:focus-visible { outline: 3px solid #fff; outline-offset: 5px; }
.card__in { /* face down in the pile; turns face up as it is dealt */
  position: absolute; inset: 0; transform-style: preserve-3d; transform: rotateY(180deg);
  transition: transform .62s var(--ease-out), translate .2s var(--ease-out); transition-delay: calc(var(--n) * 70ms + 110ms), 0s;
}
.is-dealt .card__in { transform: none; }
.is-settled .card, .is-settled .card__in { transition-delay: 0s; }
.card__face, .card__back { position: absolute; inset: 0; overflow: hidden; border: 2px solid #000; border-radius: 9px; backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.card__face { display: grid; place-items: center; background: #fff; }
.card__face .badge__face { position: relative; inset: auto; width: 78%; aspect-ratio: 1; border: 0; box-shadow: none; }
.card__back { transform: rotateY(180deg); background: repeating-linear-gradient(45deg, #000 0 5px, #fff 5px 6.500px); box-shadow: inset 0 0 0 5px #fff, inset 0 0 0 6.500px #000; }
.card:focus-visible .badge__face { filter: none; }
@media (hover: hover) and (pointer: fine) {
  .card:hover .card__in { translate: 0 -7px; }
  .card:hover .badge__face { filter: none; }
}
.is-shuffling .card:nth-child(odd) { --by: -40px; animation: riffle .3s ease-in-out 3; }
.is-shuffling .card:nth-child(even) { --by: 40px; animation: riffle .3s ease-in-out 3 .05s; }
@keyframes riffle { 50% { translate: var(--by) 0; } }

/* A small Khushi stands by the heading with a clicker in her hand, and its laser dot lands on the card being
   pointed at. The clicker is drawn in the site's red, as if with a marker: it starts blank and draws itself in. */
#decks-h { position: relative; }
.presenter { position: absolute; left: calc(100% + .2em); bottom: -.05em; display: block; --mh: 1.55em; }
.mini { display: block; height: var(--mh, 60px); pointer-events: none; user-select: none; -webkit-user-select: none; }
.mini img { display: block; height: 100%; width: auto; }
.presenter__clicker { position: absolute; width: .3em; translate: -30% -78%; rotate: 60deg; }
.wob { position: absolute; } /* holds the slight wobble that makes a drawn line look drawn by hand */
.doodle { display: block; width: 100%; height: auto; overflow: visible; fill: none; stroke: var(--red); stroke-width: 9; filter: url(#wob); }
.doodle path { stroke-dasharray: 1 2; stroke-dashoffset: 1.05; }
.doodle.is-drawn path { stroke-dashoffset: 0; transition: stroke-dashoffset .45s var(--ease-out); transition-delay: calc(var(--i) * .14s); }
.laser { position: fixed; inset: 0; z-index: 11; width: 100vw; height: 100vh; pointer-events: none; opacity: 0; transition: opacity .15s linear; }
.laser.is-on { opacity: 1; }
.laser line { stroke: var(--red); stroke-width: 1.2; opacity: .5; }
.laser circle { fill: var(--red); stroke: none; filter: drop-shadow(0 0 5px var(--red)); }
.badge {
  position: absolute; left: 0; top: 0;
  width: calc(var(--r) * 2); height: calc(var(--r) * 2);
  padding: 0; border: 0; background: none;
  cursor: grab; user-select: none; -webkit-user-select: none;
  opacity: 0; transition: opacity .35s linear; will-change: transform;
}
.badge.is-in { opacity: 1; }
.badge.is-held { cursor: grabbing; z-index: 2; }
.badge__face {
  position: absolute; inset: 0; overflow: hidden;
  display: grid; place-items: center;
  background: var(--c, #fff); color: var(--k, #000);
  border: 2px solid var(--fg, #000);
  box-shadow: 6px 6px 0 var(--fg, #000);
  filter: grayscale(1); /* black and white until hovered */
  transition: filter .25s linear, translate .2s var(--ease), box-shadow .2s var(--ease);
}
/* on a black slide the tile keeps a black edge, so its white shadow reads as a shadow and not as part of the tile */
.panel[data-tone="dark"] .badge__face { border-color: #000; }
.badge:hover .badge__face, .badge:focus-visible .badge__face, .badge.is-held .badge__face { filter: none; }
.badge:hover .badge__face, .badge:focus-visible .badge__face { translate: -3px -3px; box-shadow: 9px 9px 0 var(--fg, #000); }
.badge.is-held .badge__face { translate: -5px -5px; box-shadow: 12px 12px 0 var(--fg, #000); }
.badge:focus-visible { outline: 3px solid var(--fg, #000); outline-offset: 10px; }
.badge__name {
  padding: 0 10%; text-align: center; text-wrap: balance;
  font-family: var(--display); font-style: italic; font-weight: 400;
  font-size: calc(var(--r) * var(--fs, .36)); line-height: 1;
}
.badge__logo { width: 80%; height: 66%; object-fit: contain; pointer-events: none; }
.badge__logo--edge { width: 100%; height: 100%; } /* the tile shares the logo file's background, so it can run to the edges */
.badge__logo--fill { width: 100%; height: 100%; object-fit: cover; }

/* ---------- wins ---------- */
.wins { display: flex; align-items: center; padding: var(--top) var(--gutter) var(--foot); }
.wins__body { width: 100%; margin-left: calc(var(--desk) + clamp(28px, 6vw, 110px)); }
.wins__list {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: clamp(24px, 4vw, 72px);
  margin-top: clamp(20px, 5svh, 54px);
}
.wins__list li { padding: clamp(14px, 2.8svh, 28px) 0; border-top: 1px solid var(--fg); }
.wins__list h3 { font-family: var(--display); font-weight: 500; font-size: clamp(1.35rem, 2.3vw, 2.2rem); line-height: 1.08; }
.wins__list p { margin-top: .5em; max-width: 40ch; opacity: .85; }
.wins__list a, .wins__see { display: inline-block; margin-top: .7em; font-size: .85rem; font-weight: 800; text-underline-offset: .25em; }
.wins__list a:hover, .wins__see:hover { text-decoration-thickness: 3px; }
.wins__see { appearance: none; padding: 0; border: 0; background: none; cursor: pointer; text-decoration: underline; }
/* a win with a certificate: the words, and beside them the certificate as a small sheet lying a little askew */
.wins__list .has-proof { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: clamp(12px, 1.6vw, 26px); align-items: start; }
.wins__proof {
  display: block; width: clamp(104px, 11vw, 168px); height: auto; margin: .3em 6px 0 0;
  border: 1.5px solid var(--fg); box-shadow: 5px 5px 0 var(--fg);
  rotate: 2.5deg; cursor: zoom-in;
  filter: grayscale(1); /* black and white until hovered, like the logos */
  transition: filter .25s linear, rotate .3s var(--ease), translate .2s var(--ease), box-shadow .2s var(--ease);
}
.wins__list li:nth-child(even) .wins__proof { rotate: -2deg; }
.wins__proof:hover, .has-proof:has(.wins__see:hover, .wins__see:focus-visible) .wins__proof {
  filter: none; rotate: 0deg; translate: -3px -3px; box-shadow: 8px 8px 0 var(--fg);
}

/* ---------- the last slide ---------- */
.contact { display: flex; flex-direction: column; padding: var(--top) var(--gutter) 0; }
.contact__wrap {
  flex: 1 1 auto; min-height: 0;
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: clamp(24px, 5vw, 80px); align-items: center;
  padding-right: clamp(0px, 6vw, 110px);
}
.contact__wrap { position: relative; }
.contact__text h2:not(.sr) { margin-bottom: .5em; }
/* "Say hello" leads the slide, large, with the seal beside it */
.contact__top { display: flex; align-items: center; gap: clamp(16px, 3.2vw, 56px); }
.contact__line {
  font-family: var(--display); font-weight: 500; font-variation-settings: "opsz" 30;
  font-size: clamp(2.7rem, min(8.6vw, 17svh), 9rem); line-height: .95; letter-spacing: -.025em;
}
.contact__email {
  display: inline-block; margin-top: .42em; overflow-wrap: anywhere;
  font-family: var(--display); font-size: clamp(1.5rem, 4.300vw, 4.9rem); line-height: 1.1;
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .14em;
}
.contact__email:hover { text-decoration-thickness: 3px; }
.contact__list { display: flex; flex-wrap: wrap; gap: .5em 1.9em; margin-top: 1.5em; font-size: clamp(1rem, 1.550vw, 1.5rem); font-weight: 700; }
.contact__list a { text-underline-offset: .25em; }
.contact__list a:hover { text-decoration-thickness: 3px; }

/* The sign-off: a round red seal with the line running round its rim and a heart in the middle. It turns
   slowly, and faster while pointed at; the script leans it towards the pointer (--px, --py). A click copies
   her email address, and a few red hearts fly out of it. */
.seal {
  --seal: clamp(104px, min(13vw, 25svh), 200px);
  appearance: none; position: relative; flex: 0 0 auto; width: var(--seal); height: var(--seal); padding: 0;
  border: 0; border-radius: 50%; background: none; color: #fff; cursor: pointer;
  translate: var(--px, 0px) var(--py, 0px); transition: translate .4s var(--ease-out);
}
.seal[hidden] { display: none; }
.seal:focus-visible { outline: 3px solid #fff; outline-offset: 6px; }
.seal__disc {
  position: absolute; inset: 0; border-radius: 50%; background: var(--red);
  box-shadow: 5px 5px 0 var(--fg); /* the same hard shadow as the logo tiles */
  transition: scale .3s var(--spring), box-shadow .3s var(--ease);
}
.seal:hover .seal__disc { scale: 1.05; box-shadow: 8px 8px 0 var(--fg); }
.seal:active .seal__disc { scale: .96; box-shadow: 2px 2px 0 var(--fg); }
.seal__spin, .seal__rim { position: absolute; inset: 0; width: 100%; height: 100%; }
.seal__rim { animation: seal-turn 22s linear infinite; }
.seal__spin { animation: seal-turn 5s linear infinite paused; } /* a second, quicker turn that only runs while the seal is pointed at */
.seal:hover .seal__spin, .seal:focus-visible .seal__spin { animation-play-state: running; }
@keyframes seal-turn { to { transform: rotate(1turn); } }
.seal__rim path { stroke: none; }
.seal__rim text { fill: currentColor; stroke: none; font-family: var(--text); font-weight: 800; font-stretch: 114%; }
.seal__heart { position: absolute; left: 50%; top: 50%; width: 34%; translate: -50% -46%; }
.seal__heart svg, .seal__burst svg { display: block; width: 100%; fill: currentColor; stroke: none; }
.seal:hover .seal__heart { animation: seal-beat .9s var(--ease) infinite; }
@keyframes seal-beat { 0%, 100% { scale: 1; } 30% { scale: 1.16; } 45% { scale: .97; } 60% { scale: 1.1; } }
.seal__burst { position: absolute; left: 50%; top: 50%; width: 0; height: 0; pointer-events: none; color: var(--red); }
.seal__burst i { position: absolute; left: 0; top: 0; width: calc(var(--seal) * .17 * var(--s)); margin: calc(var(--seal) * -.085 * var(--s)); opacity: 0; }
.seal.is-popped .seal__burst i { animation: seal-pop 1.1s var(--ease-out) both; animation-delay: calc(var(--n) * 18ms); }
@keyframes seal-pop {
  0% { opacity: 0; transform: rotate(var(--a)) translateY(calc(var(--seal) * -.3)) rotate(calc(var(--a) * -1)) scale(.3); }
  18% { opacity: 1; }
  70% { opacity: 1; }
  100% { opacity: 0; transform: rotate(var(--a)) translateY(calc(var(--seal) * -1 * var(--far))) rotate(calc(var(--a) * -1)) scale(1); }
}
.seal__said { min-height: 1.5em; margin-top: .9em; font-size: .85rem; font-weight: 700; letter-spacing: .02em; } /* "Email address copied" */
/* the two buttons for seeing the slide with the seal and without */
.pick { position: absolute; left: 0; bottom: clamp(8px, 2svh, 20px); width: max-content; }
.ticker {
  margin-inline: calc(var(--gutter) * -1); padding: .55em 0;
  overflow: hidden; white-space: nowrap;
  background: var(--fg); color: var(--bg);
  font-size: .95rem; font-weight: 800; font-style: italic; font-stretch: 112%;
  letter-spacing: .03em; text-transform: uppercase;
}
.ticker__run { display: inline-flex; animation: ticker 40s linear infinite; }
.ticker__run span { padding-right: 1.2em; }
@keyframes ticker { to { transform: translateX(-50%); } }
.contact__fine { padding: .9em 0; font-size: .8rem; opacity: .8; }

/* ---------- the brand room (grows out of its tile) ---------- */
/* A certificate from the wins slide opens the same way, out of its small picture. */
.room, .proof {
  position: fixed; inset: 0; margin: 0; padding: 0; border: 0;
  width: 100vw; height: 100vh; height: 100dvh; max-width: none; max-height: none;
  overflow: hidden;
  background: var(--bg, #fff); color: var(--fg, #000);
  clip-path: inset(var(--it, 50%) var(--ir, 50%) var(--ib, 50%) var(--il, 50%));
  transition: clip-path .6s cubic-bezier(.65, 0, .2, 1), background-color .4s, color .4s;
}
.room.is-open, .proof.is-open { clip-path: inset(0); }
.room::backdrop, .proof::backdrop { background: transparent; }

.pill {
  appearance: none; cursor: pointer;
  padding: .55em 1.15em; border: 1.5px solid currentColor; border-radius: 999px; background: transparent;
  font-size: .75rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
}
.pill:hover { background: var(--fg, #000); color: var(--bg, #fff); border-color: var(--fg, #000); }
.pill--icon { display: grid; place-items: center; width: 2.9em; height: 2.9em; padding: 0; }
.pill--icon svg { width: 1.5em; height: 1.5em; stroke-width: 2; }

.room__bar {
  position: absolute; z-index: 2; top: 0; left: 0; right: 0;
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px var(--gutter);
}
.room__pager { display: flex; align-items: center; gap: .8em; font-size: .85rem; font-weight: 700; }
.room__body {
  position: absolute; inset: 0; padding-top: 70px;
  display: grid; grid-template-columns: minmax(290px, 33vw) minmax(0, 1fr); align-items: stretch;
  transition: opacity .18s linear;
}
.room__body.is-swapping { opacity: 0; }
/* her notes on the brand; they scroll on their own if there is more than fits */
.room__intro {
  min-height: 0; display: flex; overflow-y: auto; scrollbar-width: thin;
  scrollbar-color: var(--fg, #000) transparent;
  padding: 8px clamp(16px, 2vw, 32px) 16px var(--gutter);
}
.room__intro-in { margin-block: auto; width: 100%; }
.room__title { display: flex; align-items: center; gap: clamp(12px, 1.3vw, 20px); }
.room__logo:empty { display: none; }
.room__logo {
  --r: clamp(26px, 2.6vw, 38px);
  position: relative; flex: 0 0 auto; width: calc(var(--r) * 2); height: calc(var(--r) * 2);
}
.room__logo .badge__face { box-shadow: none; }
.room__logo:hover .badge__face { filter: none; }
.room__intro h2 {
  min-width: 0; font-family: var(--display); font-weight: 400; font-style: italic;
  font-size: clamp(2rem, 3.5vw, 3.4rem); line-height: .98; overflow-wrap: anywhere;
}
.room__role:empty, .room__stats:empty, .room__block:empty { display: none; }
.room__role { margin-top: .75em; font-weight: 700; line-height: 1.3; }
.room__stats { margin-top: .9em; }
.room__line { /* the brand's numbers: one small line, nothing set large */
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .15em 1.5em;
  font-size: .9rem; font-weight: 600; line-height: 1.3;
}
.room__line b { font-weight: 800; }
.room__line small { font-size: .78rem; font-weight: 600; opacity: .7; }
.room__block { margin-top: 1.1em; max-width: 42ch; font-size: .95rem; }
.room__block h3 { margin-bottom: .4em; font-size: .7rem; font-weight: 800; font-stretch: 112%; letter-spacing: .09em; text-transform: uppercase; }
.room__block p + p { margin-top: .6em; }
.room__block li { display: inline; }
.room__block li:not(:last-child)::after { content: ", "; }
/* A brand's page is in full colour all the time: its logo and every cover. */
.room__logo .badge__face { filter: none; }

/* A social brand's page is three bands, each the full width of the page. First its name with its numbers under
   it (one small line), and the skills she used boxed beside them. Then the row of work. Then her thought process.
   A deck's page keeps her notes on the left and the deck on the right. The parts are the same; here they are
   only placed differently. If the three bands are taller than the screen, the page scrolls down. */
.room[data-of="social"] .room__body {
  grid-template-columns: minmax(0, 1fr) minmax(0, auto); grid-template-rows: auto auto auto minmax(min-content, 1fr) auto;
  grid-template-areas: "title skills" "role skills" "stats skills" "shelf shelf" "thought thought";
  column-gap: clamp(20px, 4vw, 64px); overflow: hidden auto; scrollbar-width: thin;
}
.room[data-of="social"] :is(.room__intro, .room__intro-in) { display: contents; }
.room[data-of="social"] .room__title { grid-area: title; padding-left: var(--gutter); }
.room[data-of="social"] .room__role { grid-area: role; margin-top: .4em; padding-left: var(--gutter); }
.room[data-of="social"] .room__stats { grid-area: stats; align-self: start; margin-top: clamp(8px, 1.6svh, 16px); padding-left: var(--gutter); }
.room[data-of="social"] #room-skills { /* always a white box with black words, on a white page and on a black one */
  grid-area: skills; align-self: center; max-width: min(44vw, 38rem);
  margin: 0 calc(var(--gutter) + 5px) 5px 0; padding: .7em 1.1em .8em;
  background: #fff; color: #000; border: 2px solid #000; box-shadow: 5px 5px 0 var(--fg, #000);
  font-weight: 700;
}
/* the tiles are as tall as leaves room for the two bands around them */
.room[data-of="social"] .shelf { grid-area: shelf; --h: clamp(150px, 100svh - 440px, 470px); padding: 22px var(--gutter) 18px; }
.room[data-of="social"] #room-thought { grid-area: thought; max-width: none; margin: 0; padding: 0 var(--gutter) clamp(16px, 3.5svh, 34px); }
.room[data-of="social"] #room-thought h3 { margin-bottom: .55em; }
@media (min-width: 821px) { /* two paragraphs of her thinking sit side by side */
  .room[data-of="social"] #room-thought { display: grid; grid-template-columns: repeat(2, minmax(0, 62ch)); column-gap: clamp(24px, 4vw, 64px); }
  .room[data-of="social"] #room-thought h3 { grid-column: 1 / -1; }
  .room[data-of="social"] #room-thought p { margin: 0; }
  .room[data-of="social"] #room-thought p:only-of-type { grid-column: 1 / -1; max-width: 92ch; }
}

.shelf {
  --h: clamp(230px, 52svh, 520px);
  align-self: center;
  display: flex; align-items: flex-start; gap: clamp(20px, 2.6vw, 44px);
  padding: 26px var(--gutter) 26px 12px;
  overflow-x: auto; overflow-y: hidden; scrollbar-width: thin;
  scrollbar-color: var(--fg, #000) transparent;
}
.shelf__empty { font-weight: 600; }
.work, .shelf__label {
  opacity: 0; translate: 40px 0;
  transition: opacity .5s linear, translate .7s var(--ease);
  transition-delay: calc(.28s + min(var(--n), 12) * .05s);
}
.shelf.is-in .work, .shelf.is-in .shelf__label { opacity: 1; translate: 0 0; }
.shelf__label { /* names the row of work that follows it, written up the side */
  flex: 0 0 auto; height: var(--h);
  display: flex; align-items: flex-end;
  padding-right: clamp(8px, 1vw, 16px); border-right: 1px solid var(--fg, #000);
}
.shelf__label:not(:first-child) { margin-left: clamp(8px, 1.4vw, 26px); }
.shelf__label span {
  writing-mode: vertical-rl; rotate: 180deg; white-space: nowrap;
  font-size: .78rem; font-weight: 800; font-stretch: 114%; letter-spacing: .1em; text-transform: uppercase;
}
.work {
  --th: calc(var(--h) * var(--tall)); /* this tile's height */
  flex: 0 0 auto; width: max(calc(var(--th) * var(--ar)), 9.5rem);
  padding-top: calc(var(--h) - var(--th)); /* tiles of different heights stand on one line */
}
.shelf[data-count="1"] .work { --tall: .86; } /* a deck on its own gets a bigger tile */
.work__open {
  display: block; width: 100%; padding: 0; border: 0; background: none;
  text-align: left; text-decoration: none; cursor: pointer;
}
div.work__open { cursor: default; }
.work__tile {
  position: relative; display: grid; place-items: center; overflow: hidden;
  width: calc(var(--th) * var(--ar)); height: var(--th);
  background: var(--fg, #000); color: var(--bg, #fff);
  border: 1px solid var(--fg, #000); border-radius: 4px;
  transition: translate .3s var(--ease);
}
a.work__open:hover .work__tile { translate: 0 -8px; }
.work__tile img { /* covers are in their own colours all the time: a brand's page is the one place nothing waits for the pointer */
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
.work__card { /* what stands behind every cover, and shows if there is none */
  position: absolute; inset: 0; padding: calc(var(--h) * .045);
  display: flex; flex-direction: column; justify-content: space-between; align-items: flex-start;
}
.work__card small { font-size: .68rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
.work__card em {
  display: block; overflow-wrap: anywhere; text-wrap: balance;
  font-family: var(--display); font-style: italic; font-weight: 400;
  font-size: calc(var(--h) * .07); line-height: 1.04;
}
.work__card b { display: block; margin-top: .7em; font-size: .76rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
/* The shape of a tile tells you what the piece is. */
.work--reel .work__tile { border-radius: calc(var(--h) * .05); }
.work--carousel .work__tile { /* more pages peek out behind the first */
  overflow: visible;
  box-shadow:
    9px -9px 0 -1px var(--bg, #fff), 9px -9px 0 0 color-mix(in srgb, var(--fg, #000) 60%, transparent),
    18px -18px 0 -1px var(--bg, #fff), 18px -18px 0 0 color-mix(in srgb, var(--fg, #000) 35%, transparent);
}
.work--carousel { width: max(calc(var(--th) * var(--ar) + 18px), 9.5rem); }
.work--reel .work__tile::after, .work--video .work__tile::after { /* play mark */
  content: ""; position: absolute; left: 50%; top: 50%; translate: -35% -50%;
  border-style: solid; border-color: transparent transparent transparent currentColor;
  border-width: calc(var(--h) * .035) 0 calc(var(--h) * .035) calc(var(--h) * .058);
  opacity: 0;
}
.work--reel .work__tile:has(img)::after, .work--video .work__tile:has(img)::after { opacity: 1; color: #fff; filter: drop-shadow(0 1px 6px rgba(0, 0, 0, .6)); }
/* how the piece did: one large number, then the rest as a short list */
.work__nums { display: block; margin-top: .95em; }
.work__top { display: flex; align-items: baseline; gap: .45em; font-size: .9rem; font-weight: 700; }
.work__top b {
  font-family: var(--display); font-weight: 600; font-variation-settings: "opsz" 30;
  font-size: clamp(2.1rem, min(3.3vw, 6.4svh), 3.1rem); line-height: .9; letter-spacing: -.01em;
}
.work__num {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1em;
  padding: .3em 0; border-top: 1px solid color-mix(in srgb, var(--fg, #000) 35%, transparent);
  font-size: .8rem; font-weight: 600;
}
.work__num:first-of-type { margin-top: .6em; }
.work__num span::first-letter { text-transform: uppercase; }
.work__num b { font-family: var(--display); font-weight: 600; font-variation-settings: "opsz" 30; font-size: 1.3rem; line-height: 1; }
.work__cta {
  display: inline-block; margin-top: .5em;
  font-size: .74rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  text-decoration: underline; text-underline-offset: .25em;
}
.work__cta--none { text-decoration: none; opacity: .6; }
.work__note { margin-top: .3em; font-size: .9rem; opacity: .82; }

/* ---------- a certificate, full size ---------- */
/* Black, with the sheet in the middle in its own colours. The last row is breathing space under the sheet. */
.proof[open] { display: grid; grid-template-rows: auto minmax(0, 1fr) clamp(16px, 5svh, 48px); }
.proof__bar { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; padding: 16px var(--gutter); }
.proof__bar h2 { font-family: var(--display); font-weight: 400; font-style: italic; font-size: clamp(1.2rem, 2.2vw, 2rem); line-height: 1; text-align: right; }
.proof__sheet { place-self: center; max-width: min(100% - var(--gutter) * 2, 1100px); max-height: 100%; }

/* ---------- draft tab ---------- */
.draft-tab {
  position: fixed; left: 0; top: 50%; z-index: 40; translate: 0 -50%;
  writing-mode: vertical-rl; padding: .9em .35em;
  background: #000; color: #fff; border: 1px solid #fff; border-left: 0; border-radius: 0 4px 4px 0;
  font-size: .62rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  pointer-events: none;
}

/* ---------- small screens ---------- */
/* No travelling picture here: each slide stacks, and shows her in its own slot. */
@media (max-width: 820px) {
  :root { --desk: 0px; }
  .nav { top: 10px; padding: 4px; max-width: calc(100vw - 12px); overflow-x: auto; scrollbar-width: none; }
  .nav::-webkit-scrollbar { display: none; }
  .nav a { padding: .6em .58em; font-size: .6rem; letter-spacing: .04em; font-stretch: 88%; }
  .nav__home span { width: 26px; height: 26px; }

  .slot--centre, .slot--desk, .slot--side, .slot--kiss { position: relative; left: auto; bottom: auto; translate: none; }

  .hello { --word: min(33vw, 22svh); --pop: calc(clamp(64px, 11svh, 110px) + var(--word) * .9); --tall: min(98svh, 210vw); }
  .hello__word { top: clamp(64px, 11svh, 110px); translate: calc(var(--away, 0px) * -1) 0; }
  .hello__links { left: auto; right: 10px; bottom: 18px; flex-direction: column; gap: 8px; }
  .hello__links a { width: 36px; height: 36px; }

  .about { display: block; font-size: clamp(14px, 2svh, 17px); }
  .about .slot { display: none; } /* she has just been seen on the first slide */
  .about__bio, .about__facts { max-width: none; }
  .about__facts { margin-top: 2.2em; }

  /* her picture, then experience and its tools, education and languages, skills and platforms */
  .journey { display: block; font-size: clamp(13px, 1.9svh, 16px); }
  .journey__grid { display: flex; flex-direction: column; }
  .journey__cell { margin-top: 2.2em; }
  .journey__cell--exp { order: 1; margin-top: 0; }
  .journey__cell--tools { order: 2; margin-top: 1.1em; }
  .journey__cell--edu { order: 3; }
  .journey__cell--skills { order: 4; }
  .journey__cell--platforms { order: 5; margin-top: 1.1em; }
  .slot--desk, .slot--side { width: 100%; height: 32svh; margin-bottom: 1.6em; }

  .brands { display: flex; flex-direction: column; overflow: hidden auto; --side: 100%; }
  .brands__head { position: relative; left: auto; top: auto; width: auto; padding: var(--top) var(--gutter) 0; }
  .wall { position: relative; inset: auto; flex: 0 0 auto; padding: 4svh 0; --tile: min(12.5svh, 23vw); }
  .wall--drift, .wall--rings { -webkit-mask-image: none; mask-image: none; }
  .wall__lean { height: auto; rotate: -3deg; scale: 1.08; }
  /* the layout buttons sit under the heading and scroll sideways, like the menu */
  .views {
    position: static; translate: none; flex: 0 0 auto; align-self: flex-start;
    margin: 1.1em var(--gutter) 0; max-width: calc(100% - var(--gutter) * 2); overflow-x: auto; scrollbar-width: none;
  }
  .views::-webkit-scrollbar { display: none; }
  /* the layouts that need a space of their own get one; the two that are plain lists run down the slide */
  .wall--fall, .wall--globe, .wall--flip { height: 72svh; padding: 0; }
  .wall--rings { height: min(72svh, 108vw); padding: 0; }
  .wall--fall { --tile: min(13svh, 24vw); }
  /* full page: the wall fills the slide here too, behind the heading, the buttons and her picture */
  .wall--full { position: absolute; inset: 0; height: auto; }
  .brands[data-wall="full"] { overflow: hidden; }
  .brands[data-wall="full"] .views { position: relative; left: auto; margin-top: 1.4rem; }
  .brands[data-wall="full"] .slot--kiss { position: absolute; left: var(--gutter); bottom: 0; height: 44svh; margin: 0; }
  .ball { top: 50%; }
  .board { inset: 2svh var(--gutter); }
  .wall--names, .wall--grid { padding: 3svh var(--gutter) 6svh; }
  .roll, .lens { position: relative; inset: auto; }
  .roll p { font-size: clamp(1.15rem, 5.4vw, 1.6rem); }
  .roll__peek { --tile: 96px; }
  .slot--kiss { height: 34svh; min-height: 14svh; margin: 0 auto 0 var(--gutter); } /* she gives way to the wall, but never altogether */
  .slot--serious { height: 48svh; right: var(--gutter); }
  .serious { align-content: start; }
  .serious__line { max-width: none; }

  .head { flex-direction: column; align-items: flex-start; gap: .6rem; }
  .head p { max-width: none; text-align: left; }
  .decks .head h2 { font-size: clamp(1.5rem, 7.4vw, 2.1rem); } /* leaves room beside the heading for her and her clicker */

  .social { display: block; }
  .social__list { grid-template-columns: 1fr; gap: 4svh; }
  .social__list li { border-top: 1px solid var(--fg); padding-top: 3svh; }
  .social__list li:first-child { border-top: 0; padding-top: 0; }
  .social__list li + li::before { content: none; }
  .feature { height: auto; grid-template-rows: auto auto; }
  .feature__show { grid-template-rows: 40svh auto; }
  .score__top b { font-size: clamp(2.4rem, 19cqi, 4.6rem); }
  .score__rest b { font-size: clamp(1.2rem, 7.4cqi, 1.8rem); }

  .wins { display: block; }
  .wins__body { margin-left: 0; }
  .wins__list { grid-template-columns: 1fr; }

  /* (on a short phone the slide scrolls down, so the moving band never lies over the links) */
  .contact__wrap { grid-template-columns: 1fr; padding-right: 0; flex: 1 0 auto; }
  .slot--bye { --h: 34svh; justify-self: center; order: -1; }
  .contact__top { justify-content: space-between; }
  .contact__email { font-size: clamp(1.2rem, 6.200vw, 2.4rem); } /* her address stays on one line */
  .seal { margin-right: 6px; }
  .pick { position: static; margin: .6em 0 1em; }

  .room__body { display: block; overflow-y: auto; padding-top: 74px; }
  .room__intro { display: block; overflow: visible; padding: 0 var(--gutter); }
  .shelf { --h: clamp(190px, 38svh, 340px); padding: 26px var(--gutter) 34px; }
  /* a social brand's page stacks in the order of its bands: name, numbers, skills, the work, her thought process */
  .room[data-of="social"] .room__body { display: flex; flex-direction: column; }
  .room[data-of="social"] :is(.room__title, .room__role, .room__stats, .room__block, .shelf) { flex: 0 0 auto; }
  .room[data-of="social"] .room__title { order: 1; }
  .room[data-of="social"] .room__role { order: 2; }
  .room[data-of="social"] .room__stats { order: 3; padding-right: var(--gutter); }
  .room[data-of="social"] #room-skills { order: 4; max-width: none; margin: 1.1em calc(var(--gutter) + 5px) 0 var(--gutter); }
  .room[data-of="social"] .shelf { order: 5; align-self: stretch; --h: clamp(190px, 38svh, 340px); padding: 26px var(--gutter) 22px; }
  .room[data-of="social"] #room-thought { order: 6; padding-bottom: 40px; }
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: .01ms !important; transition-delay: 0s !important; animation: none !important; }
  .room, .proof { clip-path: none; opacity: 0; }
  .room.is-open, .proof.is-open { clip-path: none; opacity: 1; }
  .serious__line .w { opacity: 1; filter: none; translate: 0 0; }
  .hearts i { opacity: 1; transform: translate(calc(var(--dx) * 9vw), calc(var(--dy) * -14svh)); }
  /* (the wall stands still too: the script shows it as the grid; and the decks are already dealt, with no laser) */
}
