:root {
  /* Bright theme: the product UI's own canvas and ink colours */
  --paper: #e8eaec;
  --paper-rgb: 232, 234, 236;
  --ink: #171b1f;
  --line: #0d0d0d;
  --soft: #dedede;
  --mark-filter: invert(1);
  --interface-font: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, "PingFang SC", "Microsoft YaHei", sans-serif;
  --clepsydra-font: "Courier New", Courier, "IBM Plex Mono", "SFMono-Regular", Consolas, monospace;
  --ease: cubic-bezier(0.19, 1, 0.22, 1);
  /* Same gutter as the wordmark on clepsydra.theanalog.cc */
  --page-x: 36px;
  --gap: clamp(10px, 1.4vw, 18px);
  --note-red: #e5484d;
  --note-yellow: #f5c518;
}

/* Dark theme, matching the product UI's dark mode. Switched by clicking "for SketchUp". */
:root[data-theme="dark"] {
  --paper: #181818;
  --paper-rgb: 24, 24, 24;
  --ink: #dddddd;
  /* the 2px page frame stays a dark line in dark mode too: a light one reads as a white edge round the page */
  --line: #0d0d0d;
  --soft: #2c2c2c;
  --mark-filter: none;
}

* {
  box-sizing: border-box;
}

/* Every scroll settles on a section: hero, each demo, the six-up Branch grid, the gallery, the plans */
html {
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  /* Fallback where the page cross-fade below is not supported */
  transition: background-color 1.5s ease, color 1.5s ease;
  color: var(--ink);
  background: var(--paper);
  font-family: var(--interface-font);
  font-size: 16px;
  line-height: 1.5;
  letter-spacing: 0;
  overflow-x: hidden;
}

img {
  display: block;
  max-width: 100%;
}

.page-frame {
  position: fixed;
  inset: 0;
  z-index: 300;
  border: 2px solid var(--line);
  pointer-events: none;
}

/* Bright / dark switch: a slow cross-fade of the whole page */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 1.5s;
  animation-timing-function: ease-in-out;
}

/* Header: wordmark and Analog mark sized and placed exactly as on clepsydra.theanalog.cc */

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 84px;
  padding: 24px 36px;
  pointer-events: none;
}

/* A white fade behind the bar so the wordmark never melts into the image below it */
.site-header::before {
  content: "";
  position: absolute;
  inset: 0 0 -34px;
  z-index: -1;
  background: linear-gradient(to bottom, var(--paper) 0, rgba(var(--paper-rgb), 0.94) 44%, rgba(var(--paper-rgb), 0));
}

.site-header > * {
  pointer-events: auto;
}

/* The wordmark doubles as the hidden bright / dark switch, so it looks like plain text */
.wordmark {
  margin: 0;
  padding: 0;
  border: 0;
  color: var(--ink);
  background: none;
  font-family: var(--clepsydra-font);
  font-size: 28px;
  font-weight: 400;
  line-height: 1;
  white-space: nowrap;
  opacity: 0.9;
  cursor: default;
  outline: none;
  -webkit-tap-highlight-color: transparent;
}

.brand {
  display: flex;
  align-items: baseline;
  gap: clamp(10px, 1.4vw, 18px);
}

/* Language: one switch beside the wordmark that names the other language (中 on the English page, EN on the Chinese one).
   It waits for the wordmark to finish typing, then fades in. */
.lang {
  margin: 0;
  padding: 4px 5px;
  border: 0;
  color: var(--ink);
  background: none;
  font-family: var(--interface-font);
  font-size: 12px;
  line-height: 1;
  opacity: 0;
  pointer-events: none;
  cursor: pointer;
  transition: opacity 600ms ease;
}

.is-typed .lang {
  opacity: 0.55;
  pointer-events: auto;
}

.is-typed .lang:hover,
.is-typed .lang:focus-visible {
  opacity: 1;
}

/* Top bar: one Login button, a small version of the landing screen's filled account button
   (same ink fill, 2px border, 8px corners and the same hover: it inverts and lifts) */
.site-nav {
  display: flex;
  align-items: center;
  gap: clamp(6px, 1vw, 12px);
}

.nav-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 36px;
  padding: 8px 20px;
  border: 2px solid var(--ink);
  border-radius: 8px;
  color: var(--paper);
  background: var(--ink);
  font-size: 13px;
  line-height: 1.1;
  text-decoration: none;
  white-space: nowrap;
  transition: opacity 400ms ease, background 180ms ease, color 180ms ease, transform 180ms ease;
}

.nav-link:hover {
  color: var(--ink);
  background: var(--paper);
  transform: translateY(-2px);
}

.site-nav .mark-link {
  margin-left: clamp(2px, 0.8vw, 10px);
}

.mark-link {
  display: inline-grid;
  width: 46px;
  height: 46px;
  place-items: center;
  opacity: 0.72;
  transition: opacity 180ms ease, transform 180ms ease;
}

.mark-link:hover {
  opacity: 1;
  transform: translateY(-1px);
}

.mark-link img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: var(--mark-filter);
}

main {
  width: 100%;
  padding: 0 var(--page-x);
}

h1,
h2 {
  margin: 0;
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

h1,
h2 {
  font-size: clamp(15px, 2vw, 25px);
  line-height: 1.2;
}

h1 br,
h2 br {
  display: none;
}

/* Every statement is white text on a highlighter stroke in its section's accent colour: one thick,
   slightly bowed pass per line. The stroke is drawn in when the statement comes into view
   (the stroke itself is built in app.js to fit each line). */
h1 span,
h2 span {
  position: relative;
  z-index: 0;
  display: block;
  width: fit-content;
  color: #ffffff;
  line-height: 1.2;
}

/* the second line sits close enough that the two highlighter strokes touch */
h1 span + br + span,
h2 span + br + span {
  margin-top: 0.04em;
}

.scribble {
  position: absolute;
  z-index: -1;
  top: -0.34em;
  left: -0.55em;
  width: calc(100% + 1.1em);
  height: calc(100% + 0.68em);
  overflow: visible;
  pointer-events: none;
}

.scribble path {
  fill: none;
  /* each section sets its own highlighter colour */
  stroke: var(--accent, var(--ink));
  /* a chisel tip: flat ends */
  stroke-linecap: butt;
  stroke-linejoin: round;
}

.scribble-text {
  opacity: 0;
  transition: opacity 260ms ease;
}

.is-scribbled .scribble path {
  stroke-dashoffset: 0 !important;
  transition: stroke-dashoffset var(--scribble-time, 700ms) cubic-bezier(0.4, 0, 0.3, 1) var(--scribble-delay, 0ms);
}

.is-scribbled .scribble-text {
  opacity: 1;
  transition-delay: calc(var(--scribble-delay, 0ms) + 260ms);
}

/* Landing: the first screen, as on the current clepsydra.theanalog.cc — the particle crescent,
   the typed wordmark above it and the two account buttons below. */
.landing {
  position: relative;
  left: 50%;
  width: 100vw;
  height: 100svh;
  min-height: 420px;
  margin-left: -50vw;
  overflow: hidden;
  scroll-snap-align: start;
}

.particle-field {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0.28;
}

:root[data-theme="dark"] .particle-field {
  opacity: 0.4;
}

.auth-area {
  position: absolute;
  left: 50%;
  bottom: clamp(76px, 10vh, 118px);
  z-index: 2;
  display: grid;
  width: clamp(520px, 66vw, 720px);
  max-width: calc(100vw - 48px);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: center;
  gap: 18px;
  transform: translateX(-50%);
}

.auth-pill,
.auth-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 13px 24px;
  border: 2px solid var(--ink);
  border-radius: 8px;
  font-size: 15px;
  line-height: 1.1;
  text-decoration: none;
  transition: background 180ms ease, color 180ms ease, transform 180ms ease;
}

.auth-pill {
  color: var(--ink);
  background: rgba(var(--paper-rgb), 0.72);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

.auth-cta {
  color: var(--paper);
  background: var(--ink);
}

.auth-pill:hover,
.auth-cta:hover {
  transform: translateY(-2px);
}

.auth-pill:hover {
  color: var(--paper);
  background: var(--ink);
}

.auth-cta:hover {
  color: var(--ink);
  background: var(--paper);
}

/* the wordmark types itself in, with the blinking cursor of the current landing page */
.type-cursor {
  display: inline-block;
  width: 1px;
  height: 0.88em;
  background: currentColor;
  transform: translateY(0.08em);
  animation: cursor-blink 1s steps(1, end) infinite;
}

@keyframes cursor-blink {
  50% {
    opacity: 0;
  }
}

@media (max-width: 680px) and (orientation: portrait) {
  .particle-field {
    opacity: 0.2;
  }

  .auth-area {
    left: 24px;
    right: 24px;
    bottom: 76px;
    width: auto;
    grid-template-columns: 1fr;
    gap: 12px;
    transform: none;
  }
}

/* Hero: the hover reveal fills the first screen and sits behind the statement */

.hero {
  scroll-snap-align: start;
  position: relative;
  left: 50%;
  width: 100vw;
  height: 100svh;
  min-height: 520px;
  margin-left: -50vw;
  overflow: hidden;
}

.hero .reveal {
  position: absolute;
  inset: 0;
  aspect-ratio: auto;
}



/* The image melts into the page at its lower edge, so the hero has no hard bottom line */
.hero::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  height: 30%;
  background: linear-gradient(to bottom, rgba(var(--paper-rgb), 0) 0, rgba(var(--paper-rgb), 0.72) 62%, var(--paper) 100%);
  pointer-events: none;
}

.hero-copy {
  position: absolute;
  z-index: 4;
  left: var(--page-x);
  right: var(--page-x);
  bottom: clamp(40px, 9vh, 88px);
  pointer-events: none;
}

/* Chapters: each is exactly one screen. The demo fills all of it and the statement sits on top,
   so the demos run on from one another without a title band between them. */

.chapter {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100svh;
  min-height: 420px;
  scroll-snap-align: start;
}

.chapter-copy {
  position: absolute;
  z-index: 5;
  /* Bottom-left, like the hero's statement, with its left edge on the wordmark's left edge */
  bottom: clamp(40px, 9vh, 88px);
  left: 0;
  right: 0;
  margin: 0;
  pointer-events: none;
}

/* The Branch chapter is longer than a screen: its stops are set inside it */
.chapter--branches {
  display: block;
  height: auto;
  padding: 0;
  scroll-snap-align: none;
}

.snap-stop {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 100svh;
  pointer-events: none;
  scroll-snap-align: start;
}

.snap-stop--end {
  top: auto;
  bottom: 0;
}

/* Live UI replicas: a fixed 1600 x 880 screen fitted into what is left of the screen below the title.
   Its background is the page's own colour, so any band beside or below it does not show. */

.screen,
.markup-fit {
  left: 50%;
  width: 100vw;
  margin-left: -50vw;
}

.screen {
  position: relative;
  flex: 1 1 0;
  min-height: 0;
  overflow: hidden;
  background: var(--paper);
  cursor: pointer;
}

.screen iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 1600px;
  height: 880px;
  border: 0;
  transform: translate(var(--screen-shift, 0px), var(--screen-drop, 0px)) scale(var(--screen-scale, 1));
  transform-origin: 0 0;
  pointer-events: none;
}

/* The Board on three devices, drawn flat: a desktop display where the team works live, a tablet where
   someone marks up an image with a pencil, and a phone where someone swipes and zooms around the canvas. */
.desk {
  position: absolute;
  inset: 0;
}

.mac {
  position: absolute;
  top: 104px;
  left: 6vw;
  width: min(60vw, calc((100svh - 190px) / 0.82));
  filter: drop-shadow(0 22px 30px rgba(0, 0, 0, 0.18));
}

/* a thin, even black bezel with a fine aluminium edge and nearly square corners */
.mac-display {
  position: relative;
  z-index: 1;
  padding: 1.15%;
  border-radius: 0.9% / 1.6%;
  background: #050506;
  box-shadow: 0 0 0 1.5px #1b1b1d, 0 0 0 2.5px #b9bbc0;
}

/* inside the display the screen is an ordinary box, not the full-bleed one used elsewhere */
.mac-display .screen {
  left: 0;
  width: 100%;
  margin: 0;
  flex: none;
  aspect-ratio: 1600 / 880;
  border-radius: 0;
}

/* the stand: one wide, flat slab of matte aluminium, a quarter of the display's width and as tall as it is wide,
   shaded only where it tucks up behind the display */
.mac-neck {
  position: relative;
  width: 25%;
  aspect-ratio: 1 / 0.96;
  margin: 0 auto;
  background:
    linear-gradient(to bottom, rgba(0, 0, 0, 0.3) 0, rgba(0, 0, 0, 0.08) 5%, rgba(0, 0, 0, 0) 13%),
    linear-gradient(to right, #b7b9be 0, #cfd1d5 5%, #d8dadd 50%, #cfd1d5 95%, #b4b6bb 100%);
  box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.5), inset -1px 0 0 rgba(0, 0, 0, 0.08);
}

/* its foot: a slim base plate the same width, a shade darker, standing on two small pads */
.mac-foot {
  position: relative;
  width: 25%;
  height: clamp(4px, 0.75vw, 11px);
  margin: 0 auto;
  background: linear-gradient(to bottom, #eeeff1 0, #c6c8cc 35%, #a9abb0 100%);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.22);
}

.mac-foot::before,
.mac-foot::after {
  content: "";
  position: absolute;
  top: 100%;
  width: 7%;
  height: 22%;
  min-height: 1.5px;
  background: #8f9095;
}

.mac-foot::before {
  left: 5%;
}

.mac-foot::after {
  right: 5%;
}

/* Tablet and phone: the Board open in Safari, each panning and zooming around the live canvas by itself */
.device {
  --ios-bar: #f5f5f7;
  --ios-field: rgba(118, 118, 128, 0.14);
  --ios-ink: #111113;
  --ios-tint: #0a7aff;
  position: absolute;
  z-index: 4;
  overflow: hidden;
  color: var(--ios-ink);
  background: var(--ios-bar);
  box-shadow: 0 0 0 1.5px #d4d6da, 0 0 0 2.5px #8f9197, 0 22px 44px rgba(0, 0, 0, 0.28);
  font-family: -apple-system, "SF Pro Text", "Helvetica Neue", Helvetica, Arial, sans-serif;
  pointer-events: none;
}

:root[data-theme="dark"] .device {
  --ios-bar: #1c1c1e;
  --ios-field: rgba(118, 118, 128, 0.3);
  --ios-ink: #f2f2f4;
  --ios-tint: #4b9bff;
}

/* The screen is laid out at a fixed design width and scaled down to the device (app.js sets --k and --dh).
   Its text is therefore set at normal sizes: phone browsers enforce a minimum font size, which blew up
   the tiny type this used to have when it was sized directly at the device's real width. */
.device-inner {
  position: absolute;
  top: 0;
  left: 0;
  width: var(--dw);
  height: var(--dh, 100%);
  display: flex;
  flex-direction: column;
  container-type: inline-size;
  transform: scale(var(--k, 1));
  transform-origin: 0 0;
  -webkit-text-size-adjust: none;
  text-size-adjust: none;
}

.device--pad {
  --dw: 1000px;
}

.device--phone {
  --dw: 300px;
}

.device-view {
  position: relative;
  flex: 1 1 0;
  min-height: 0;
  overflow: hidden;
  background: var(--paper);
}

.device iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 1600px;
  height: 880px;
  border: 0;
  transform-origin: 0 0;
}

.ios-status,
.safari {
  flex: none;
  display: flex;
  align-items: center;
}

.ios-status {
  justify-content: space-between;
  font-weight: 600;
}

.ios-right {
  display: flex;
  align-items: center;
}

.ios-signal {
  background: linear-gradient(to right, currentColor 0 18%, transparent 18% 27%, currentColor 27% 45%, transparent 45% 54%, currentColor 54% 72%, transparent 72% 81%, currentColor 81% 100%);
  clip-path: polygon(0 62%, 18% 62%, 18% 42%, 45% 42%, 45% 22%, 72% 22%, 72% 0, 100% 0, 100% 100%, 0 100%);
}

.ios-battery {
  border: 1px solid currentColor;
  background: linear-gradient(currentColor, currentColor) 12% 50% / 68% 62% no-repeat;
  opacity: 0.9;
}

.safari svg {
  flex: none;
  color: var(--ios-tint);
}

.safari svg.is-dim {
  opacity: 0.35;
}

.safari-icons {
  display: flex;
  align-items: center;
}

.safari-address {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ios-field);
}

.safari-address b {
  font-weight: 400;
  white-space: nowrap;
}

.safari-address svg {
  color: var(--ios-ink);
  opacity: 0.55;
}

/* iPad: status bar and Safari's toolbar along the top */
.device--pad {
  right: 5vw;
  bottom: 9svh;
  width: 31vw;
  aspect-ratio: 4 / 3;
  border: clamp(6px, 0.95vw, 15px) solid #0b0b0d;
  border-radius: clamp(12px, 1.7vw, 26px);
}

.device--pad .ios-status {
  height: 3.4cqw;
  padding: 0 2.4cqw;
  font-size: 1.55cqw;
}

.device--pad .ios-signal {
  width: 2.2cqw;
  height: 1.3cqw;
  margin-right: 1cqw;
}

.device--pad .ios-battery {
  width: 3cqw;
  height: 1.4cqw;
  border-radius: 0.4cqw;
}

.safari--pad {
  justify-content: space-between;
  height: 5.6cqw;
  padding: 0 2cqw 0.6cqw;
  box-shadow: 0 1px 0 rgba(128, 128, 128, 0.25);
}

.safari--pad .safari-icons {
  gap: 2.2cqw;
}

.safari--pad svg {
  width: 2.5cqw;
  height: 2.5cqw;
}

.safari--pad .safari-address {
  gap: 0.6cqw;
  width: 48cqw;
  height: 4cqw;
  border-radius: 1.2cqw;
  font-size: 1.6cqw;
}

.safari--pad .safari-address svg {
  width: 1.5cqw;
  height: 1.5cqw;
}

.safari--pad .safari-address svg:last-child {
  margin-left: auto;
  margin-right: 1.2cqw;
  width: 1.9cqw;
  height: 1.9cqw;
}

.safari--pad .safari-address svg:first-child {
  margin-left: auto;
}

/* iPhone: status bar beside the camera island, Safari's address bar and toolbar at the bottom */
.device--phone {
  right: 39vw;
  bottom: 6svh;
  width: 9.6vw;
  aspect-ratio: 9 / 19.5;
  border: clamp(4px, 0.5vw, 8px) solid #0b0b0d;
  border-radius: clamp(14px, 1.9vw, 30px);
}

.device--phone::after {
  content: "";
  position: absolute;
  z-index: 3;
  top: 2.2%;
  left: 50%;
  width: 30%;
  height: 3.4%;
  border-radius: 999px;
  background: #050506;
  transform: translateX(-50%);
}

.device--phone .ios-status {
  height: 15cqw;
  padding: 2cqw 8cqw 0;
  font-size: 4.6cqw;
}

.device--phone .ios-signal {
  width: 5.5cqw;
  height: 3.4cqw;
  margin-right: 2cqw;
}

.device--phone .ios-battery {
  width: 7.5cqw;
  height: 3.6cqw;
  border-radius: 1.1cqw;
}

.safari--phone {
  flex-direction: column;
  align-items: stretch;
  padding: 3cqw 4cqw 2.4cqw;
  box-shadow: 0 -1px 0 rgba(128, 128, 128, 0.25);
}

.safari--phone .safari-address {
  gap: 1.4cqw;
  height: 12cqw;
  border-radius: 4cqw;
  font-size: 4.3cqw;
}

.safari--phone .safari-address svg {
  width: 3.8cqw;
  height: 3.8cqw;
}

.safari--phone .safari-address svg:first-child {
  margin-left: auto;
}

.safari--phone .safari-address svg:last-child {
  margin-left: auto;
  margin-right: 3cqw;
  width: 4.6cqw;
  height: 4.6cqw;
}

.safari--phone .safari-icons {
  justify-content: space-between;
  height: 13cqw;
  padding: 0 3cqw;
}

.safari--phone .safari-icons svg {
  width: 6.6cqw;
  height: 6.6cqw;
}

.ios-home {
  width: 36cqw;
  height: 1.4cqw;
  margin: 0 auto;
  border-radius: 999px;
  background: var(--ios-ink);
}

/* Held upright: the display on top, the tablet and the phone side by side beneath it */
@media (orientation: portrait) {
  .mac {
    top: 92px;
    left: 6vw;
    width: 88vw;
  }

  .device--pad {
    top: calc(92px + 88vw * 0.81 + 4svh);
    right: auto;
    bottom: auto;
    left: 7vw;
    width: 52vw;
  }

  .device--phone {
    top: calc(92px + 88vw * 0.81 + 2svh);
    right: auto;
    bottom: auto;
    left: 67vw;
    width: 21vw;
  }
}

/* Branches: the first Branch fills the screen; scrolling on shrinks it into a grid and five more join it */

.branches {
  position: relative;
  left: 50%;
  width: 100vw;
  height: calc(100svh + 130vh);
  margin-left: -50vw;
}

/* The Branch stage is full width, so its statement needs the page gutter itself */
.branches-title {
  z-index: 3;
  left: var(--page-x);
  right: var(--page-x);
}

.branches-stage {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
}

.branch-tile {
  position: absolute;
  top: 0;
  left: 0;
  overflow: hidden;
  border-radius: 10px;
  will-change: transform, width, height, opacity;
}

.branch-tile--lead {
  z-index: 2;
  cursor: pointer;
}

/* When Run is clicked the group grows a result column: ease the frame out to fit it */
.branch-tile.is-widening,
.branch-tile.is-widening iframe {
  transition: transform 0.9s var(--ease), width 0.9s var(--ease), height 0.9s var(--ease);
}

.branch-tile iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 1600px;
  height: 880px;
  border: 0;
  transform: translate(var(--ox, 0px), var(--oy, 0px)) scale(var(--s, 1));
  transform-origin: 0 0;
  pointer-events: none;
}

/* Mood gallery: SketchUp scene + mood image = generated result, one screen tall.
   Wide screens: the result fills the screen, with the scene and the mood inset over its lower-left corner
   and the six moods to pick from over its lower-right. Held upright: stacked. */

.moodboard {
  position: relative;
  z-index: 3;
  left: 50%;
  width: 100vw;
  min-height: 100svh;
  margin-left: -50vw;
  padding: 104px var(--page-x) 24px;
  scroll-snap-align: start;
}

.mood-eq {
  position: relative;
  width: min(100%, calc((100svh - 128px) * 16 / 9));
  margin: 0 auto;
  aspect-ratio: 16 / 9;
}

.mood-cell {
  position: absolute;
  overflow: hidden;
  border-radius: 10px;
  background: var(--soft);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}

.mood-cell--result {
  inset: 0;
}

.mood-cell--source,
.mood-cell--target {
  z-index: 2;
  bottom: 3.5%;
  height: 24%;
  border: 2px solid var(--paper);
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.35);
}

.mood-cell--source {
  left: 2.2%;
  aspect-ratio: 16 / 9;
}

.mood-cell--target {
  left: 30.6%;
  aspect-ratio: 3 / 4;
}

.mood-cell img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 700ms ease;
}

.mood-cell img.is-on {
  opacity: 1;
}

.mood-op {
  position: absolute;
  z-index: 2;
  bottom: 15.5%;
  left: 28.4%;
  color: #ffffff;
  font-family: var(--clepsydra-font);
  font-size: clamp(22px, 2.6vw, 40px);
  line-height: 1;
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.6);
  transform: translate(-50%, 50%);
}

.mood-op--equals {
  left: 42.9%;
}

.mood-picks {
  position: absolute;
  z-index: 2;
  right: 2.2%;
  bottom: 3.5%;
  display: flex;
  gap: 10px;
}

.mood-pick {
  width: clamp(40px, 4.4vw, 66px);
  aspect-ratio: 3 / 4;
  padding: 0;
  overflow: hidden;
  border: 0;
  border-radius: 6px;
  background: none;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
  opacity: 0.6;
  cursor: pointer;
  transition: opacity 300ms ease, box-shadow 300ms ease;
}

.mood-pick img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.mood-pick.is-on {
  opacity: 1;
  box-shadow: 0 0 0 2px var(--paper), 0 0 0 3.5px var(--ink);
}

.mood-pick:focus-visible {
  outline: 1.5px solid var(--ink);
  outline-offset: 3px;
}

/* Held upright: scene and mood side by side, the result full width below, the moods under it */
@media (orientation: portrait), (max-width: 760px) {
  .mood-eq {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 0.42fr);
    grid-template-areas:
      "source plus target"
      "equals equals equals"
      "result result result"
      "picks picks picks";
    align-items: center;
    gap: 8px clamp(10px, 1.6vw, 26px);
    width: 100%;
    aspect-ratio: auto;
  }

  .mood-cell {
    position: relative;
    inset: auto;
    left: auto;
    bottom: auto;
    height: auto;
    border: 0;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  }

  .mood-cell--source {
    grid-area: source;
    aspect-ratio: 16 / 9;
  }

  .mood-cell--target {
    grid-area: target;
    aspect-ratio: 3 / 4;
  }

  .mood-cell--result {
    grid-area: result;
    aspect-ratio: 16 / 9;
  }

  .mood-op {
    position: static;
    grid-area: plus;
    color: inherit;
    text-shadow: none;
    opacity: 0.55;
    transform: none;
  }

  .mood-op--equals {
    grid-area: equals;
    justify-self: center;
  }

  .mood-picks {
    position: static;
    grid-area: picks;
    justify-content: center;
    margin-top: 6px;
  }

  .mood-pick {
    box-shadow: none;
    opacity: 0.45;
  }
}

/* From the six Branches into the gallery: each generated image narrows where it is, then glides down
   to become one of the gallery's thumbnails, while the rest of the gallery fades in behind. */
.fly-layer {
  position: fixed;
  inset: 0;
  z-index: 150;
  pointer-events: none;
}

.fly {
  position: absolute;
  top: 0;
  left: 0;
  background: center / cover no-repeat;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.22);
  will-change: transform, width, height;
}

.moodboard.is-flying .mood-cell,
.moodboard.is-flying .mood-op {
  opacity: var(--arrive, 0);
  transition: none;
}

.moodboard.is-flying .mood-pick {
  opacity: 0;
  transition: none;
}

/* Hover reveal: a soft spotlight of the result follows the pointer (same trick as the front page) */

.reveal {
  --reveal-x: 50%;
  --reveal-y: 50%;
  --reveal-radius: 0px;
  --reveal-falloff: 0px;
  position: relative;
  margin: 0;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  outline: none;
  background: #eef3f7;
  cursor: none;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
}

.reveal-before,
.reveal-after,
.reveal-after img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.reveal-before,
.reveal-after img {
  object-fit: cover;
}

.reveal-after {
  z-index: 2;
  -webkit-mask-image: radial-gradient(
    circle at var(--reveal-x) var(--reveal-y),
    #000 0,
    #000 var(--reveal-radius),
    transparent calc(var(--reveal-radius) + var(--reveal-falloff))
  );
  mask-image: radial-gradient(
    circle at var(--reveal-x) var(--reveal-y),
    #000 0,
    #000 var(--reveal-radius),
    transparent calc(var(--reveal-radius) + var(--reveal-falloff))
  );
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

.reveal-logo {
  position: absolute;
  z-index: 6;
  top: var(--reveal-y);
  left: var(--reveal-x);
  width: 18px;
  height: 18px;
  object-fit: contain;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(0.86);
  filter: drop-shadow(0 2px 4px rgb(12 22 31 / 32%));
  transition: opacity 120ms ease, transform 160ms ease;
}

.reveal.has-logo-pointer .reveal-logo {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

.reveal:focus-visible {
  box-shadow: inset 0 0 0 2px var(--ink);
}

/* Mark-up demo: notes are sketched and typed onto the image, then it updates */

.markup-fit {
  position: relative;
  flex: 1 1 0;
  min-height: 0;
  display: grid;
  place-items: center;
  container-type: size;
}

.markup {
  position: relative;
  width: min(100cqw, 100cqh * 16 / 9);
  margin: 0;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  container-type: inline-size;
  background: var(--soft);
}

.markup-base,
.markup-result,
.markup-ink {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.markup-base,
.markup-result {
  object-fit: cover;
}

.markup-result {
  opacity: 0;
  transition: opacity 900ms ease;
}

.markup.is-updated .markup-result {
  opacity: 1;
}

.markup-ink,
.markup-note {
  transition: opacity 500ms ease;
}

.markup.is-updated .markup-ink,
.markup.is-updated .markup-note {
  opacity: 0;
}

.ink {
  fill: none;
  stroke-width: 5;
  stroke-linecap: round;
  stroke-linejoin: round;
  /* marker-like: a touch soft at the edges */
  filter: blur(0.25px);
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}

.ink--red {
  stroke: var(--note-red);
}

.ink--yellow {
  stroke: var(--note-yellow);
}

.ink.is-drawn {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset var(--ink-time, 1200ms) cubic-bezier(0.5, 0.05, 0.3, 1);
}

.markup-note {
  position: absolute;
  z-index: 2;
  margin: 0;
  font-family: Inter, "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 1.75cqw;
  font-weight: 700;
  line-height: 1.22;
  white-space: pre;
}

.markup-note--red {
  /* low enough to clear the top bar's fade, and still inside the red outline */
  top: 11.5%;
  left: 52%;
  color: var(--note-red);
  font-size: 2.6cqw;
}

.markup-note--yellow {
  top: 75.4%;
  left: 26.6%;
  color: var(--note-yellow);
  font-size: 2.6cqw;
}

.markup-note.is-typing::after {
  content: "";
  display: inline-block;
  width: 0.08em;
  height: 0.95em;
  margin-left: 0.08em;
  background: currentColor;
  vertical-align: -0.1em;
}

/* Two dots in the note colours invite a click; each one plays its note */
.markup-dot {
  position: absolute;
  z-index: 4;
  width: clamp(24px, 2.6cqw, 40px);
  aspect-ratio: 1;
  padding: 0;
  border: 2.5px solid #ffffff;
  border-radius: 50%;
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.35);
  cursor: pointer;
  transform: translate(-50%, -50%);
  transition: opacity 300ms ease, transform 300ms ease;
}

.markup-dot::before,
.markup-dot::after {
  content: "";
  position: absolute;
  inset: -2.5px;
  border-radius: 50%;
  background: inherit;
  opacity: 0;
  animation: markup-ping 2s ease-out infinite;
  pointer-events: none;
}

.markup-dot::after {
  animation-delay: 0.6s;
}

.markup-dot--red {
  top: 21%;
  left: 72%;
  background: var(--note-red);
}

.markup-dot--yellow {
  top: 75%;
  left: 17.6%;
  background: var(--note-yellow);
}

/* The image arrives by growing out of the last result card of the section above; the dots wait until it lands */
.markup {
  transform-origin: 0 0;
  will-change: transform;
}

.markup:not(.is-landed) .markup-dot {
  opacity: 0;
  pointer-events: none;
}

.markup-dot.is-used {
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.4);
  pointer-events: none;
}

@keyframes markup-ping {
  0% {
    opacity: 0.55;
    transform: scale(1);
  }

  80%,
  100% {
    opacity: 0;
    transform: scale(2.6);
  }
}

.markup-status {
  position: absolute;
  z-index: 3;
  left: 50%;
  bottom: 5%;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 18px;
  border-radius: 999px;
  color: #171b1f;
  background: rgba(235, 235, 235, 0.94);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  font-family: Inter, "Lucida Grande", "Lucida Sans Unicode", Arial, sans-serif;
  font-size: 13px;
  opacity: 0;
  transform: translate(-50%, 8px);
  transition: opacity 320ms ease, transform 320ms ease;
  pointer-events: none;
}

.markup.is-working .markup-status {
  opacity: 1;
  transform: translate(-50%, 0);
}

.markup-spinner {
  width: 14px;
  height: 14px;
  border: 2px solid rgba(17, 17, 17, 0.18);
  border-top-color: #111111;
  border-radius: 50%;
  animation: markup-spin 800ms linear infinite;
}

@keyframes markup-spin {
  to {
    transform: rotate(360deg);
  }
}

/* Plans: Individual / Business tabs over large cards, centred in the screen. Every card reads top to bottom:
   who it is for, the name, the price, how much usage it carries against Basic, then the button.
   All bars share one scale (10x is a full bar), and grow in when the section or tab appears. */

.pricing {
  --fg: 5, 5, 5;
  --card: rgba(255, 255, 255, 0.55);
  position: relative;
  left: 50%;
  width: 100vw;
  margin: 0 0 0 -50vw;
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding: 104px var(--page-x) 40px;
  color: var(--ink);
  scroll-snap-align: start;
}

:root[data-theme="dark"] .pricing {
  --fg: 255, 255, 255;
  --card: rgba(255, 255, 255, 0.045);
}

.pricing-shell {
  width: min(940px, 100%);
  margin: 0 auto;
  text-align: center;
}

.pricing-tabs {
  display: inline-flex;
  margin-bottom: clamp(18px, 3.4vh, 32px);
  padding: 3px;
  border-radius: 999px;
  background: rgba(var(--fg), 0.06);
  font-size: 12px;
  line-height: 1.2;
}

.pricing-tab {
  min-width: 108px;
  min-height: 30px;
  padding: 6px 18px;
  border: 0;
  border-radius: 999px;
  color: rgba(var(--fg), 0.6);
  background: transparent;
  font: inherit;
  cursor: pointer;
  transition: background 220ms ease, color 220ms ease;
}

.pricing-tab.is-active {
  color: var(--paper);
  background: var(--ink);
}

.pricing-tab:not(.is-active):hover {
  color: var(--ink);
}

.pricing-tab:focus-visible {
  outline: 1.5px solid rgba(var(--fg), 0.5);
  outline-offset: 2px;
}

.plans {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(10px, 1.2vw, 16px);
  text-align: left;
}

.plans--individual {
  grid-template-columns: repeat(2, minmax(0, calc((100% - 2 * clamp(10px, 1.2vw, 16px)) / 3)));
  justify-content: center;
}

.plans[hidden] {
  display: none;
}

.plan {
  display: flex;
  flex-direction: column;
  padding: clamp(18px, 1.8vw, 24px);
  border: 1px solid rgba(var(--fg), 0.12);
  border-radius: 10px;
  background: var(--card);
  transition: border-color 220ms ease, transform 220ms ease, box-shadow 220ms ease;
}

.plan:hover,
.plan:focus-within {
  position: relative;
  z-index: 5;
  border-color: rgba(var(--fg), 0.4);
  transform: translateY(-2px);
}

/* each card eases up as its tab opens */
.plans.is-growing .plan {
  animation: plan-in 520ms var(--ease) both;
  animation-delay: var(--delay, 0ms);
}

@keyframes plan-in {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
}

.plan-type {
  margin: 0;
  color: rgba(var(--fg), 0.55);
  font-family: var(--clepsydra-font);
  font-size: 12px;
  line-height: 1;
}

.plan h3 {
  margin: 10px 0 0;
  font-size: 20px;
  font-weight: 400;
  line-height: 1.1;
}

.plan-note {
  min-height: 2.7em;
  margin: 6px 0 0;
  color: rgba(var(--fg), 0.55);
  font-size: 12px;
  line-height: 1.35;
}

.plan-price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 8px;
  margin: clamp(14px, 2.4vh, 22px) 0 0;
  line-height: 1;
}

.plan-price b {
  font-size: 26px;
  font-weight: 400;
  letter-spacing: -0.01em;
}

.plan-price span {
  color: rgba(var(--fg), 0.55);
  font-size: 11px;
}

.plan-meter {
  margin-top: clamp(14px, 2.4vh, 22px);
}

.plan-meter-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  color: rgba(var(--fg), 0.55);
  font-size: 11px;
}

.plan-meter-top b {
  color: var(--ink);
  font-size: 12px;
  font-weight: 400;
}

.plan-track {
  position: relative;
  height: 3px;
  margin-top: 8px;
  overflow: hidden;
  border-radius: 999px;
  background: rgba(var(--fg), 0.1);
}

.plan-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--level, 10%);
  border-radius: inherit;
  background: var(--ink);
  transform-origin: left center;
}

.plan > .plan-action,
.plan > .plan-action-wrap {
  margin-top: clamp(16px, 2.6vh, 24px);
}

/* On the landing and plans screens the top bar's Login button steps aside: the two large account buttons are there */
.site-header.is-at-plans .nav-link,
.site-header.is-at-landing .nav-link {
  opacity: 0;
  pointer-events: none;
}

/* the same two buttons as on the landing screen, under the plans */
.pricing-signin {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
  width: clamp(520px, 66vw, 720px);
  max-width: 100%;
  margin: clamp(22px, 4vh, 38px) auto 0;
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity 500ms ease 150ms, transform 500ms var(--ease) 150ms;
}

.pricing.is-current .pricing-signin {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

@media (max-width: 680px) and (orientation: portrait) {
  .pricing-signin {
    grid-template-columns: 1fr;
    gap: 12px;
    width: 100%;
  }
}

.pricing-terms {
  margin: clamp(16px, 2.8vh, 26px) 0 0;
  font-family: var(--clepsydra-font);
  font-size: 12px;
}

.pricing-terms a {
  color: rgba(var(--fg), 0.55);
  text-underline-offset: 4px;
  transition: color 180ms ease;
}

.pricing-terms a:hover {
  color: var(--ink);
}

/* Plan buttons, as on clepsydra.theanalog.cc: individual plans link to sign-up, business plans
   show a note that they are sold through partners */
.plan-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 34px;
  margin-top: 0;
  padding: 8px 14px;
  border: 1px solid rgba(var(--fg), 0.55);
  border-radius: 999px;
  color: var(--ink);
  background: var(--card);
  font: inherit;
  font-size: 12px;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: background 180ms ease, color 180ms ease, transform 180ms ease;
}

.plan-action:hover {
  color: var(--paper);
  background: var(--ink);
  transform: translateY(-1px);
}

.plan-action-wrap {
  position: relative;
  z-index: 20;
}

.plan-action-wrap .plan-action {
  margin-top: 0;
}

.plan-action--channel,
.plan-action--channel:hover,
.plan-action--channel:focus-visible {
  border-color: rgba(var(--fg), 0.28);
  color: rgba(var(--fg), 0.46);
  background: rgba(var(--fg), 0.05);
  cursor: default;
  transform: none;
}

.plan-action--channel:hover,
.plan-action--channel:focus-visible {
  border-color: rgba(var(--fg), 0.32);
  color: var(--ink);
  background: rgba(var(--fg), 0.08);
}

.plan-tooltip {
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  z-index: 100;
  width: max-content;
  max-width: min(320px, calc(100vw - 48px));
  padding: 9px 12px;
  border: 1px solid rgba(var(--fg), 0.18);
  border-radius: 8px;
  color: var(--ink);
  background: var(--paper);
  box-shadow: 0 14px 38px rgba(0, 0, 0, 0.14);
  font-size: 12px;
  line-height: 1.25;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, -4px);
  transition: opacity 160ms ease, transform 160ms ease;
}

.plan-action-wrap:hover .plan-tooltip,
.plan-action-wrap:focus-within .plan-tooltip,
.plan-action-wrap.is-tooltip-open .plan-tooltip {
  opacity: 1;
  transform: translate(-50%, 0);
}

.plans.is-growing .plan-fill {
  animation: plan-grow 1s ease both;
  animation-delay: calc(var(--delay, 0ms) + 250ms);
}

@keyframes plan-grow {
  from {
    transform: scaleX(0);
  }
}

/* Scroll reveal */

.reveal-ready [data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}

.reveal-ready [data-reveal].is-in {
  opacity: 1;
  transform: none;
}

/* Narrower screens: two cards across, then one; the section scrolls if it is taller than the screen */
@media (max-width: 900px) {
  .pricing {
    align-items: flex-start;
  }

  .plans,
  .plans--individual {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    justify-content: stretch;
  }
}

@media (max-width: 560px) {
  .pricing-tabs {
    display: flex;
  }

  .pricing-tab {
    flex: 1 1 0;
    min-width: 0;
  }

  .plans,
  .plans--individual {
    grid-template-columns: 1fr;
  }

  .plan {
    padding: 18px;
  }

  .plan-note {
    min-height: 0;
  }
}

@media (max-width: 760px) {
  .markup-status {
    padding: 7px 12px;
    font-size: 11px;
  }
}

/* Same phone breakpoint as clepsydra.theanalog.cc */
@media (max-width: 560px) {
  :root {
    --page-x: 22px;
  }

  .site-header {
    min-height: 74px;
    padding: 18px 22px;
  }

  .wordmark {
    font-size: 20px;
  }

  .site-nav {
    gap: 2px;
  }

  .brand {
    gap: 6px;
  }

  .lang {
    padding: 4px 3px;
    font-size: 11px;
  }

  .nav-link {
    min-height: 30px;
    padding: 6px 14px;
    font-size: 12px;
  }

  .site-nav .mark-link {
    width: 30px;
    height: 30px;
  }

  .mark-link {
    width: 38px;
    height: 38px;
  }

}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .reveal-ready [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .type-cursor,
  .markup-spinner,
  .markup-dot::before,
  .markup-dot::after {
    animation: none;
  }
}
