/* Limit Notch - product page. One page, no build step, no outside requests.
   The panels (.np) are drawn like the app's own: same sizes, colours and motion. */

:root {
  --bg: #050508;
  --text: #f3f3f6;
  --muted: rgba(243, 243, 246, .58);
  --faint: rgba(243, 243, 246, .32);
  --line: rgba(255, 255, 255, .08);
  /* The icon's gradient, a little brighter for light on black. */
  --red: #d2554a;
  --plum: #7b4d6c;
  --blue: #3a6f9e;
  --claude: #f0883e;
  /* As in the app: a limit near its end, and a limit reset there to use. */
  --danger: #ff5a52;
  --fresh: #5ad08f;
  --track: rgba(255, 255, 255, .25);
  /* The app's motion curve: eases in, then out. */
  --glide: cubic-bezier(.4, 0, .2, 1);
  --mono: "Cascadia Mono", "Cascadia Code", Consolas, ui-monospace, "SF Mono", Menlo, monospace;
  --font: "Segoe UI Variable Display", "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; }
html { background: var(--bg); color-scheme: dark; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
a { color: inherit; }
h1, h2, p { margin: 0; }

/* ---- the panel, shared by the live notch and the one on the demo screen ------------- */

.np {
  border-radius: 0 0 8px 8px;
  background: rgba(0, 0, 0, .42);
  -webkit-backdrop-filter: blur(22px) saturate(150%);
  backdrop-filter: blur(22px) saturate(150%);
  box-shadow: 0 14px 40px -16px rgba(0, 0, 0, .9), inset 0 -1px 0 rgba(255, 255, 255, .06);
  color: #fff;
  overflow: hidden;
}
/* Both layers are centred on the panel; max-content keeps that from squeezing their columns
   into the half of the panel that lies right of the centre. */
.np .notch-mini {
  position: absolute;
  top: 0;
  left: 50%;
  width: max-content;
  height: 24px;
  display: flex;
  align-items: center;
  gap: 10px;
  transform: translateX(-50%);
  transition: opacity 200ms ease-out 170ms;
}
.np.open .notch-mini { opacity: 0; transition: opacity 100ms ease-out; }
.mini-group { display: flex; flex-direction: column; gap: 3px; }
.mini-bar {
  display: block;
  width: 52px;
  height: 5px;
  border-radius: 3px;
  background: var(--track);
  overflow: hidden;
}
/* As in the app, the colour turns to red towards the end of the bar - of the whole bar: the
   gradient is as wide as the track, not as the filled part, so the colour says how far along the
   limit it is. */
.mini-bar b, .bar b {
  --fill: var(--claude);
  display: block;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--fill) 60%, var(--danger)) 0 0 / calc(10000% / max(var(--p), 1)) 100% no-repeat;
}
.mini-bar b { width: max(5px, calc(var(--p) * 1%)); }
.chatgpt .mini-bar b, .bar.chatgpt b { --fill: #fff; }

/* The open panel: service | label | bar | percent | time, rows of 24, as in the app. */
.notch-full {
  position: absolute;
  top: 10px;
  left: 50%;
  width: max-content;
  display: grid;
  grid-template-columns: auto auto 140px auto auto;
  grid-template-rows: 24px 24px 6px 24px;
  align-items: center;
  white-space: nowrap;
  letter-spacing: .6px;
  text-align: left;
  opacity: 0;
  transform: translate(-50%, -8px);
  transition: opacity 110ms ease-out, transform 140ms var(--glide);
}
.np.open .notch-full {
  opacity: 1;
  transform: translate(-50%, 0);
  transition: opacity 230ms ease-out 190ms, transform 230ms var(--glide) 190ms;
}
.gap, .name.head { grid-column: 1 / -1; }
.name { font-size: 14px; font-weight: 600; padding-right: 12px; }
.name.head { padding-right: 0; }
.label { font-size: 14px; font-weight: 500; color: #d6d6d6; padding-right: 10px; }
.bar {
  width: 140px;
  height: 8px;
  margin-top: 4px;
  border-radius: 4px;
  background: var(--track);
  overflow: hidden;
}
.bar b { width: max(8px, calc(var(--p) * 1%)); }
.pct { font-size: 15px; font-weight: 600; padding-left: 9px; }
.time {
  display: flex;
  align-items: center;
  gap: 3px;
  max-width: 0;
  overflow: hidden;
  opacity: 0;
  font-size: 14px;
  font-weight: 500;
  color: #e6e6e6;
  transition: max-width 420ms var(--glide), padding 420ms var(--glide), opacity 110ms ease-out;
}
.np.times .time {
  max-width: 120px;
  padding-left: 10px;
  opacity: 1;
  transition: max-width 420ms var(--glide), padding 420ms var(--glide), opacity 220ms ease-out 160ms;
}
/* Going: they fade out while the panel keeps its width. */
.np.times.times-out .time { opacity: 0; transition: opacity 110ms ease-out; }
/* A pixel lower, as in the app, so the icons sit level with the digits beside them. */
.time svg { width: 12px; height: 12px; margin-top: 1px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
/* Sizes are measured once, without any motion. */
.np.measure, .np.measure * { transition: none !important; }

/* The two layouts: in a row, or - against a side edge - one service under the other, the
   names above their rows. Changing between them cross-fades while the shape glides. */
.np .lay { position: absolute; inset: 0; }
/* As in the app: the old layout goes at once, the new one fades in. */
.np:not(.side) .lay.stack, .np.side .lay.row { opacity: 0; }
.np:not(.side) .lay.row, .np.side .lay.stack { animation: lay-in 220ms ease-out; }
@keyframes lay-in { from { opacity: 0; } }
.np .lay.stack .notch-mini { top: 8px; height: auto; flex-direction: column; gap: 6px; }
.np .lay.stack .notch-full { grid-template-columns: auto 140px auto auto; grid-template-rows: 24px 24px 24px 6px 24px 24px; }
/* Against an edge only the corners away from it are rounded; loose, all four are. */
.np.loose { border-radius: 8px; }
.np.right { border-radius: 8px 0 0 8px; }
.np.left { border-radius: 0 8px 8px 0; }

/* The live one, at the top of this window; script places and sizes it. Its place and size
   move together, on the same curve, so it opens around its centre or from its edge. */
.notch {
  position: fixed;
  z-index: 50;
  top: 0;
  left: calc(50% - 73px);
  width: 146px;
  height: 29px;
  padding: 0;
  margin: 0;
  border: 0;
  font: inherit;
  cursor: default;
  touch-action: none;
  transition: left 360ms var(--glide), top 360ms var(--glide), width 360ms var(--glide), height 360ms var(--glide), border-radius 260ms var(--glide),
    translate 520ms var(--glide), opacity 420ms var(--glide);
}
.notch.open { transition-duration: 420ms, 420ms, 420ms, 420ms, 260ms, 520ms, 420ms; }
/* On the screen with the demo it steps out of the way, off the edge it is on: the demo shows it. */
.notch.away { translate: 0 calc(-100% - 12px); opacity: 0; pointer-events: none; }
.notch.away.left { translate: calc(-100% - 12px) 0; }
.notch.away.right { translate: calc(100% + 12px) 0; }
.notch.away.loose { translate: 0 -16px; }
/* While dragged it follows the pointer at once; joining or leaving an edge glides, drawn frame by
   frame by the script (so no transition of place or size then). */
.notch.dragging { cursor: grabbing; transition: width 420ms var(--glide), height 420ms var(--glide), border-radius 260ms var(--glide); }
.notch.morph { transition: border-radius 220ms var(--glide), translate 520ms var(--glide), opacity 420ms var(--glide); }
.notch:focus-visible { outline: 2px solid rgba(255, 255, 255, .7); outline-offset: 2px; }

/* ---- hero ---------------------------------------------------------------------------- */

.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  place-items: center;
  overflow: hidden;
  isolation: isolate;
}

/* Slow, soft light in the icon's colours: the wallpaper the notch sits on. Long ribbons that
   cross and blend into each other. */
.aurora { position: absolute; inset: 0; z-index: -2; overflow: hidden; }
.hero .aurora { opacity: .62; }
.aurora span {
  position: absolute;
  border-radius: 50%;
  filter: blur(60px);
  will-change: transform;
}
.aurora span:nth-child(1) {
  width: 96vmax; height: 21vmax; left: -22vmax; top: -9vmax;
  background: linear-gradient(90deg, transparent 5%, var(--red) 35%, var(--claude) 62%, transparent 92%);
  transform: rotate(-14deg);
  opacity: .72;
  animation: ribbon-a 28s var(--glide) infinite alternate;
}
.aurora span:nth-child(2) {
  width: 102vmax; height: 23vmax; right: -30vmax; top: -5vmax;
  background: linear-gradient(90deg, transparent 5%, var(--plum) 32%, var(--blue) 66%, transparent 94%);
  transform: rotate(17deg);
  opacity: .8;
  animation: ribbon-b 34s var(--glide) infinite alternate;
}
.aurora span:nth-child(3) {
  width: 64vmax; height: 4.5vmax; left: calc(50% - 32vmax); top: 3vmax;
  background: linear-gradient(90deg, transparent, rgba(240, 136, 62, .9) 50%, transparent);
  filter: blur(26px);
  transform: rotate(-5deg);
  opacity: .55;
  animation: ribbon-c 22s var(--glide) infinite alternate;
}
.hero .aurora::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 80% 70% at 50% 30%, transparent 30%, var(--bg) 92%);
}
@keyframes ribbon-a { to { transform: rotate(-7deg) translate(8vmax, 5vmax) scaleX(1.1); } }
@keyframes ribbon-b { to { transform: rotate(9deg) translate(-9vmax, 7vmax) scaleX(.9); } }
@keyframes ribbon-c { to { transform: rotate(4deg) translate(5vmax, 4vmax); } }

.hero-inner { text-align: center; padding: 0 20px; }
h1 {
  font-size: clamp(56px, 12vw, 164px);
  font-weight: 600;
  line-height: .95;
  letter-spacing: -.045em;
  background: linear-gradient(180deg, #fff 35%, rgba(255, 255, 255, .5));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: rise 1.2s var(--glide) both;
}
.tagline {
  margin-top: 22px;
  font-size: clamp(18px, 2.2vw, 25px);
  font-weight: 400;
  color: var(--muted);
  animation: rise 1.2s var(--glide) .12s both;
}
/* The tagline comes in a few letters at a time, the way an AI's answer streams, with a caret
   that blinks a while at its end. Script splits it up; without script it is just there. */
/* Each piece comes out of a blur, gently, while the next ones follow. */
.tagline .tk { opacity: 0; filter: blur(7px); transition: opacity .55s ease-out, filter .7s var(--glide); }
.tagline .tk.on { opacity: 1; filter: blur(0); }
.caret { position: relative; display: inline-block; width: 0; }
.caret::after {
  content: "";
  position: absolute;
  left: .14em;
  bottom: -.2em;
  width: .48em;
  height: 1.08em;
  border-radius: 1px;
  background: var(--claude);
  animation: blink 1s steps(1) infinite;
}
.caret.gone { opacity: 0; transition: opacity .5s; }
@keyframes blink { 50% { opacity: 0; } }
/* Decoding: each letter keeps its own width while code characters run through it. */
.decoding span { display: inline-block; white-space: pre; text-align: center; }
.decoding .g { font-family: var(--mono); font-weight: 500; color: var(--claude); opacity: .85; }

/* The button is made of the panel's own glass, with its corners, over a soft glow that
   shows through it the way the wallpaper shows through the notch. */
.cta {
  position: relative;
  display: inline-block;
  margin-top: 42px;
  isolation: isolate;
  animation: rise 1.2s var(--glide) .24s both;
}
.cta .glow {
  position: absolute;
  inset: -12px -36px;
  z-index: -1;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 255, 255, .22), transparent);
  filter: blur(12px);
  opacity: .8;
  transition: opacity .4s var(--glide), transform .6s var(--glide);
}
.store {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 15px 44px 16px;
  border: 0;
  border-radius: 8px;
  background: linear-gradient(180deg, rgba(255, 255, 255, .17), rgba(255, 255, 255, .08));
  -webkit-backdrop-filter: blur(22px) saturate(150%);
  backdrop-filter: blur(22px) saturate(150%);
  box-shadow: 0 14px 40px -16px rgba(0, 0, 0, .9), inset 0 0 0 1px rgba(255, 255, 255, .1), inset 0 1px 0 rgba(255, 255, 255, .22);
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .12em;
  text-decoration: none;
  transition: transform .35s var(--glide), background .35s var(--glide);
}
.cta, .store { transition: translate .6s var(--glide), transform .35s var(--glide), background .35s var(--glide); }
.cta.pull, .cta.pull .store { transition: translate .18s ease-out, transform .35s var(--glide), background .35s var(--glide); }
.cta:hover .glow { opacity: 1; transform: scale(1.08); }
.store:hover { background: linear-gradient(180deg, rgba(255, 255, 255, .24), rgba(255, 255, 255, .12)); transform: translateY(-1px); }
.store:focus-visible { outline: 2px solid #fff; outline-offset: 4px; }
.meta {
  margin-top: 20px;
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: .04em;
  color: var(--muted);
  animation: rise 1.2s var(--glide) .36s both;
}
@keyframes rise { from { opacity: 0; transform: translateY(18px); } }

/* "Try it": a short guide under the notch - open it, click it, drag it. Script keeps it under the
   panel as that opens and changes its words; it goes once the panel has been dragged. */
.try {
  position: absolute;
  top: 43px;
  left: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  transform: translateX(-50%);
  pointer-events: none;
  animation: try-in .9s var(--glide) 1.4s backwards;
  transition: top 400ms var(--glide), left 400ms var(--glide), opacity .4s;
}
.try .pill {
  display: flex;
  align-items: center;
  gap: 11px;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .8);
  text-shadow: 0 1px 12px rgba(0, 0, 0, .5);
  white-space: nowrap;
}
.try .say { transition: opacity .18s ease-out; }
/* Before it has been opened, "Try" and "Click it" take turns: each comes out of a blur with a
   flash of light, stays a moment and fades, while the other comes. */
.try .alt { display: grid; justify-items: center; }
/* The turns begin as the hint itself comes in (its try-in, 1.4s after the page), "Try" first. */
.try .alt b { grid-area: 1 / 1; font-weight: inherit; opacity: 0; animation: turn 3.4s ease-in-out 1.4s infinite backwards; }
.try .alt b + b { animation-delay: 3.1s; }
@keyframes turn {
  0% { opacity: 0; filter: blur(4px); text-shadow: 0 0 0 rgba(255, 255, 255, 0); }
  9% { opacity: 1; filter: blur(0); text-shadow: 0 0 18px rgba(255, 255, 255, .6); }
  26% { text-shadow: 0 0 0 rgba(255, 255, 255, 0); }
  42% { opacity: 1; filter: blur(0); }
  50%, 100% { opacity: 0; filter: blur(4px); text-shadow: 0 0 0 rgba(255, 255, 255, 0); }
}
.try.swap .say { opacity: 0; }
.try.seen { opacity: 0; }
@keyframes try-in { from { opacity: 0; transform: translate(-50%, -8px); } }

/* "Scroll", at the foot of the first screen; gone once the page has been scrolled. */
.scroll-hint {
  position: absolute;
  left: 50%;
  bottom: 22px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  transform: translateX(-50%);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .3em;
  text-indent: .3em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .42);
  pointer-events: none;
  animation: try-in .9s var(--glide) 2s backwards;
  transition: opacity .5s var(--glide);
}
.scrolled .scroll-hint { opacity: 0; }

/* ---- sections ------------------------------------------------------------------------ */

section:not(.hero) { padding: 16vh 20px; text-align: center; position: relative; }
h2 {
  font-size: clamp(38px, 6.4vw, 92px);
  font-weight: 600;
  line-height: 1.02;
  letter-spacing: -.04em;
}
.reveal > * { opacity: 0; transform: translateY(28px); transition: opacity 1s var(--glide), transform 1s var(--glide); }
.reveal.in > * { opacity: 1; transform: none; }
.reveal.in > *:nth-child(2) { transition-delay: .12s; }
.reveal.in > *:nth-child(3) { transition-delay: .24s; }
.reveal.in > *:nth-child(4) { transition-delay: .36s; }
.reveal.in > *:nth-child(5) { transition-delay: .48s; }

/* How it works: a screen, the panel on it, and a cursor using it. */
.monitor {
  width: min(980px, 100%);
  margin: 0 auto;
  padding: clamp(6px, 1.2vw, 12px);
  border-radius: clamp(12px, 2vw, 22px);
  background: linear-gradient(180deg, #1b1b22, #0b0b0f);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .07), 0 40px 120px -40px rgba(58, 111, 158, .5), 0 30px 90px -40px rgba(210, 85, 74, .45);
}
.screen {
  position: relative;
  aspect-ratio: 16 / 10;
  border-radius: clamp(6px, 1.1vw, 12px);
  overflow: hidden;
  background: #0a0a10;
}
/* A 1100 x 687.5 desktop, scaled to the screen, so the panel keeps the app's own sizes. */
.desk {
  position: absolute;
  left: 0;
  top: 0;
  width: 1100px;
  height: 687.5px;
  transform: scale(var(--s, .8));
  transform-origin: 0 0;
  overflow: hidden;
  isolation: isolate;
}
/* On the small screen the same ribbons, blurred much more for their size, so no edge shows. */
.aurora.small span { filter: blur(70px); animation-duration: 40s; }
.aurora.small span:nth-child(1) { width: 1500px; height: 330px; left: -430px; top: -90px; }
.aurora.small span:nth-child(2) { width: 1600px; height: 380px; right: -580px; left: auto; top: -10px; }
.aurora.small span:nth-child(3) { width: 1000px; height: 70px; left: 50px; top: 60px; filter: blur(34px); }
/* On the demo's desktop: a terminal where an AI is at work - what the panel keeps count of. New
   lines come in at the bottom and push the old ones up and out. */
.term {
  position: absolute;
  left: 64px;
  top: 150px;
  width: 560px;
  height: 330px;
  display: flex;
  flex-direction: column;
  border-radius: 10px;
  background: rgba(10, 10, 15, .74);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  box-shadow: 0 30px 80px -30px rgba(0, 0, 0, .9), inset 0 0 0 1px rgba(255, 255, 255, .06);
  font: 500 14px/1.7 var(--mono);
  color: rgba(255, 255, 255, .8);
  text-align: left;
  overflow: hidden;
}
/* As on Windows: a tab at the left, the window's buttons at the right. */
.term-bar { display: flex; align-items: flex-end; justify-content: space-between; height: 40px; padding: 0 0 0 10px; }
.term-tab {
  padding: 7px 16px 8px;
  border-radius: 7px 7px 0 0;
  background: rgba(255, 255, 255, .07);
  font: 500 12px/1 var(--font);
  letter-spacing: .02em;
  color: rgba(255, 255, 255, .75);
}
.term-win { display: flex; align-self: center; gap: 30px; padding-right: 18px; }
.term-win svg { width: 10px; height: 10px; fill: none; stroke: rgba(255, 255, 255, .55); stroke-width: 1; }
.term-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 6px 22px 18px;
  overflow: hidden;
  white-space: pre;
  transition: opacity .5s;
}
.term-body.out { opacity: 0; }
.term-body p { animation: line-in .25s ease-out; }
.term-body .you { margin-top: 10px; color: #fff; }
.term-body .you::before { content: "> "; color: var(--claude); }
.term-body .tool::before { content: "\25CF  "; color: var(--claude); }
.term-body .dim { color: rgba(255, 255, 255, .45); }
.term-body .fail { color: #ff8a80; }
.term-body .say { color: rgba(255, 255, 255, .92); }
/* Lines an edit adds, as the terminal shows them: green, on a band of their own. */
.term-body .add { margin: 0 -22px; padding: 0 22px; background: rgba(90, 208, 143, .1); color: #a6e9c3; }
.term-body .add::before { content: "  + "; color: var(--fresh); }
.term-body .typing::after {
  content: "";
  display: inline-block;
  width: .55em;
  height: 1.05em;
  margin-left: 1px;
  vertical-align: -.18em;
  background: rgba(255, 255, 255, .7);
  animation: blink 1s steps(1) infinite;
}
@keyframes line-in { from { opacity: 0; transform: translateY(4px); } }
.taskbar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 48px;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 12px;
  background: rgba(10, 10, 14, .6);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border-top: 1px solid rgba(255, 255, 255, .06);
}
.taskbar i { width: 24px; height: 24px; border-radius: 6px; background: rgba(255, 255, 255, .14); }

.dn {
  position: absolute;
  left: 477px;
  top: 0;
  width: 146px;
  height: 29px;
  transition: left var(--d, 420ms) var(--glide), top var(--d, 420ms) var(--glide),
    width 420ms var(--glide), height 420ms var(--glide), border-radius 260ms var(--glide);
}
/* Joining or leaving an edge: one short glide for everything. */
.dn.morph { transition: left 220ms var(--glide), top 220ms var(--glide), width 220ms var(--glide), height 220ms var(--glide), border-radius 220ms var(--glide); }

.dcur {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 5;
  width: 20px;
  height: 25px;
  fill: #fff;
  stroke: #15151a;
  stroke-width: 1.1;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .6));
  opacity: 0;
  transform: translate(var(--x, 880px), var(--y, 560px));
  transition: transform var(--d, 800ms) var(--glide), opacity .35s;
}
.dcur.on { opacity: 1; }
.ring {
  position: absolute;
  left: -18px;
  top: -18px;
  z-index: 4;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .85);
  opacity: 0;
  pointer-events: none;
}
.ring.go { animation: ring .6s var(--glide); }
@keyframes ring {
  from { opacity: .9; transform: translate(var(--x), var(--y)) scale(.25); }
  to { opacity: 0; transform: translate(var(--x), var(--y)) scale(1.3); }
}

/* A limit reset to use, at the end of ChatGPT's line as in the app (against a side edge, on the
   line with its name): always on the live panel, which lights it up as it opens; on the demo's in
   its fifth step, with the notification that told of it in the corner of the screen. */
.np .lay.row .notch-full { grid-template-columns: auto auto 140px auto auto auto; }
.notch .badge { display: flex; }
.notch .name.head, .dn .name.head { display: flex; align-items: center; justify-content: space-between; }
.notch.open .badge { animation: badge-in 1.4s ease-out .45s both; }
.badge .time { color: var(--fresh); }
.np.times .badge .time { padding-left: 6px; }
.dn .badge { display: none; }
.dn.reset .badge { display: flex; }
.badge { align-items: center; gap: 4px; padding-left: 12px; font-size: 14px; font-weight: 600; color: var(--fresh); }
.badge svg { width: 12px; height: 12px; margin-top: 1px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.dn.open.reset .badge { animation: badge-in 1.4s ease-out .45s both; }
@keyframes badge-in {
  0% { opacity: 0; transform: scale(.6); }
  25% { opacity: 1; transform: scale(1.12); filter: drop-shadow(0 0 6px rgba(90, 208, 143, .9)); }
  60%, 100% { opacity: 1; transform: none; filter: drop-shadow(0 0 0 rgba(90, 208, 143, 0)); }
}
/* The notification, as Windows 11 shows the app's: in the corner above the taskbar. */
.toast {
  position: absolute;
  right: 14px;
  bottom: 62px;
  width: 364px;
  border-radius: 8px;
  background: rgba(43, 43, 43, .96);
  border: 1px solid rgba(255, 255, 255, .12);
  box-shadow: 0 16px 40px -8px rgba(0, 0, 0, .55);
  color: #fff;
  font-family: "Segoe UI Variable Text", "Segoe UI", system-ui, sans-serif;
  text-align: left;
  opacity: 0;
  transform: translateX(calc(100% + 40px));
  transition: transform .6s var(--glide), opacity .4s ease-out;
}
.toast.in { opacity: 1; transform: none; }
.toast-head { display: flex; align-items: center; height: 44px; padding: 0 14px 0 16px; font-size: 12px; color: #e4e4e4; }
.toast-head span { flex: 1; }
.toast-head i { margin-left: 22px; font-style: normal; font-size: 13px; color: #c9c9c9; }
.toast-body { display: flex; gap: 16px; padding: 4px 16px 20px; }
.toast-body img { flex: none; width: 24px; height: 24px; margin-top: 2px; }
.toast-body b { display: block; font-size: 14px; font-weight: 600; }
.toast-body span { display: block; margin-top: 2px; font-size: 14px; color: #c9c9c9; }

/* Four steps, shown as bars filling like the app's own. */
.steps { display: flex; justify-content: center; gap: 10px; margin-top: 46px; }
.steps i { display: block; width: 46px; height: 4px; border-radius: 2px; background: rgba(255, 255, 255, .14); overflow: hidden; }
.steps b { display: block; width: 0; height: 100%; border-radius: inherit; background: var(--claude); }
.caption {
  margin-top: 22px;
  min-height: 1.4em;
  font-size: clamp(20px, 2.4vw, 30px);
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--text);
  transition: opacity .3s ease-out, transform .3s var(--glide);
}
.caption.out { opacity: 0; transform: translateY(8px); }
.caption .w { opacity: .28; transition: opacity .35s ease-out; }
.caption .w.on { opacity: 1; }
.caption .fresh { color: var(--fresh); }

/* Text painted with a gradient shows only inside its box: room below for the g's and y's. */
h1, .private h2 { padding-bottom: .14em; }
/* The colour flows through it without end: the gradient is one tile that begins and ends alike,
   and it moves by exactly one tile each round. */
.private h2 {
  background: linear-gradient(90deg, #fff, #fde3cf 14%, var(--claude) 38%, #e9784f 56%, #fde3cf 84%, #fff);
  background-size: 200% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: sheen 6s linear infinite;
}
.private p { margin-top: 26px; letter-spacing: .1em; color: var(--muted); font-size: clamp(16px, 1.6vw, 19px); }
@keyframes sheen { from { background-position: 0 0; } to { background-position: -200% 0; } }

.get { position: relative; isolation: isolate; padding-bottom: 14vh; }
/* The code on the ground fades out towards the icon, the name and the button. */
.get::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(ellipse 44% 54% at 50% 47%, var(--bg) 50%, rgba(5, 5, 8, .8) 72%, transparent);
  pointer-events: none;
}
/* The icon lights the dark around it in its own colours: a blurred copy of it behind, which
   breathes slowly. */
.get-mark {
  position: relative;
  display: block;
  width: 128px;
  height: 128px;
  margin: 0 auto 40px;
}
.get-mark::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: url(assets/icon-256.png) center / contain no-repeat;
  filter: blur(40px) saturate(1.6);
  opacity: .7;
  transform: translateY(12px) scale(1.28);
  animation: halo 7s ease-in-out infinite alternate;
}
@keyframes halo { to { opacity: .5; transform: translateY(15px) scale(1.4); } }
.get-icon { display: block; width: 128px; height: 128px; }
.get h2 {
  font-size: clamp(36px, 5vw, 64px);
  letter-spacing: -.02em;
  background: linear-gradient(180deg, #fff 40%, rgba(255, 255, 255, .62));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.get .meta, .get .cta { animation: none; }

footer {
  padding: 34px 20px 44px;
  border-top: 1px solid var(--line);
  text-align: center;
  font-size: 15px;
  letter-spacing: .16em;
  color: var(--muted);
}
footer p > span { margin: 0 16px; }
footer a { text-decoration: none; }
/* The maker's name comes out of ones and zeros, as it does on its own site: over the name itself,
   unseen, the changing one is squeezed or stretched to the same width. */
.bits { position: relative; display: inline-block; white-space: nowrap; }
.bits .size { visibility: hidden; }
.bits .out { position: absolute; top: 0; left: 0; display: flex; width: max-content; transform-origin: left center; }
.bits [data-bit] { font-variant-numeric: tabular-nums; color: var(--faint); }
footer a:hover { color: var(--text); }

/* ---- the trip: four screens side by side and one below the other, travelled through by
   scrolling - right, down, then left. Script turns it on (class "travel"); without it, or with
   less motion wanted, the page is an ordinary column. ------------------------------------- */

html { scrollbar-width: none; }
html::-webkit-scrollbar { display: none; }
.map { display: none; }
.travel .world { position: relative; }
.travel .stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  overflow: clip;
}
/* The ground the screens stand on: faint lines of code (script draws them), which show the travel. */
.travel .plane {
  position: absolute;
  left: 0;
  top: 0;
  width: 200%;
  height: 200%;
  will-change: transform;
}
.travel .panel {
  position: absolute;
  width: 50%;
  height: 50%;
  min-height: 0;
  padding: 0 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.travel .panel[data-at="0 0"] { left: 0; top: 0; }
.travel .panel[data-at="1 0"] { left: 50%; top: 0; }
.travel .panel[data-at="1 1"] { left: 50%; top: 50%; }
.travel .panel[data-at="0 1"] { left: 0; top: 50%; }
.travel .demo .monitor { width: min(980px, 100%, calc((100svh - 230px) * 1.6)); }
.travel .get footer { position: absolute; left: 0; right: 0; bottom: 0; }

/* Where you are: the screens as squares, in their own arrangement. */
.travel .map {
  position: fixed;
  right: 22px;
  bottom: 22px;
  z-index: 40;
  display: grid;
  grid-template-columns: repeat(2, 10px);
  gap: 5px;
}
.map button {
  width: 10px;
  height: 10px;
  padding: 0;
  border: 0;
  border-radius: 3px;
  background: rgba(255, 255, 255, .22);
  cursor: pointer;
  transition: background .3s, transform .3s var(--glide);
}
.map button:hover { background: rgba(255, 255, 255, .55); transform: scale(1.15); }
.map button.on { background: var(--claude); }
.map button:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }


/* ---- the pointer: the code under the page lights up around it. Script draws it, behind the
   screens (which come after it), so it never covers a word. -------------------------------- */

.code { position: fixed; left: 0; top: 0; width: 100vw; height: 100vh; pointer-events: none; }

/* ---- the pointer itself: a caret, as in a terminal, and a ring that follows a moment later.
   It blinks while the pointer rests; over what can be clicked or dragged the ring opens. Script
   adds it, and hides the system's arrow, only with a mouse. ----------------------------- */

.own-cursor, .own-cursor * { cursor: none !important; }
.cur-caret, .cur-ring { position: fixed; left: 0; top: 0; z-index: 100; pointer-events: none; opacity: 0; transition: opacity .3s; }
.cursor-on .cur-caret, .cursor-on .cur-ring { opacity: 1; }
.cur-caret {
  width: 5px;
  height: 16px;
  margin: -8px 0 0 -2.5px;
  border-radius: 1px;
  background: var(--claude);
  box-shadow: 0 0 10px rgba(240, 136, 62, .5);
  transition: opacity .3s, scale .25s var(--glide);
}
.cur-caret.idle { animation: blink 1.05s steps(1) infinite; }
/* The ring is drawn as a circle, which stays smooth at every size; its size changes, not a scale. */
.cur-ring {
  width: 24px;
  height: 24px;
  margin: -12px 0 0 -12px;
  transition: opacity .3s, width .3s var(--glide), height .3s var(--glide), margin .3s var(--glide);
}
.cur-ring svg { display: block; width: 100%; height: 100%; overflow: visible; }
.cur-ring circle {
  fill: rgba(240, 136, 62, 0);
  stroke: rgba(255, 255, 255, .5);
  stroke-width: 1.8;
  vector-effect: non-scaling-stroke;
  transition: stroke .3s, fill .3s;
}
.cursor-over .cur-ring { width: 30px; height: 30px; margin: -15px 0 0 -15px; }
.cursor-down .cur-ring { width: 18px; height: 18px; margin: -9px 0 0 -9px; }
.cursor-over.cursor-down .cur-ring { width: 26px; height: 26px; margin: -13px 0 0 -13px; }
.cursor-drag .cur-ring { opacity: 0; }

/* ---- small screens and less motion --------------------------------------------------- */

@media (max-width: 640px) {
  section:not(.hero) { padding: 12vh 16px; }
  .steps { margin-top: 32px; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .reveal > * { opacity: 1; transform: none; }
}
