@font-face { font-family: 'Anybody'; src: url(/fonts/anybody-latin-wdth-normal.woff2) format('woff2'); font-weight: 100 900; font-stretch: 50% 150%; font-display: block; }
@font-face { font-family: 'Atkinson Next'; src: url(/fonts/atkinson-hyperlegible-next-latin-wght-normal.woff2) format('woff2'); font-weight: 200 800; font-display: swap; }
@font-face { font-family: 'Atkinson Mono'; src: url(/fonts/atkinson-hyperlegible-mono-latin-wght-normal.woff2) format('woff2'); font-weight: 200 800; font-display: swap; }

:root {
  --field: #0B0B3B;      /* deep ultramarine base, lit by the ambient gradients */
  --field-deep: rgba(11, 11, 59, .6); /* chips and inputs sitting on the background */
  --ink: #F6F4EF;        /* paper white for the password and text */
  --soft: rgba(246, 244, 239, .74);
  --line: rgba(246, 244, 239, .24);
  --accent: #FFB8CF;     /* separators, digits, focus */
  --display: 'Anybody', 'Arial Narrow', system-ui, sans-serif;
  --body: 'Atkinson Next', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'Atkinson Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  color-scheme: dark;
}

/* Ambient background: soft radial light over deep ultramarine, with a little grain.
   Built from plain gradients on one screen-sized layer instead of blurred shapes, an
   oversized grain layer and blend modes: same look, far less graphics memory on phones.
   (Swapped after a reload loop on an iPhone on 23-sep-2026; the old version was later
   seen working there, so it was a precaution, not a confirmed cause.) */
.ambient { position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(circle 55vmax at 8% 0%, rgba(43, 43, 217, .55), transparent 70%),
    radial-gradient(circle 45vmax at 100% 55%, rgba(61, 43, 217, .32), transparent 70%),
    radial-gradient(circle 35vmax at 50% 105%, rgba(255, 184, 207, .16), transparent 70%); }
.ambient::after { content: ''; position: absolute; inset: 0; opacity: .05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--field); color: var(--ink);
  font: 400 1.0625rem/1.55 var(--body);
  padding: env(safe-area-inset-top, 0) 0 env(safe-area-inset-bottom, 0);
}
.wrap { max-width: 1280px; margin: 0 auto; padding-inline: clamp(16px, 4vw, 48px); }

.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; border-radius: 6px; }
button { font: inherit; color: inherit; cursor: pointer; }

/* Header */
.top { display: flex; justify-content: space-between; align-items: center; padding-block: 22px; gap: 16px; }
.mark { color: var(--ink); text-decoration: none; font: 300 1.05rem/1 var(--display); font-stretch: 125%; letter-spacing: -.01em; }
.mark b { font-weight: 700; }
.langs { display: flex; gap: 4px; }
.langs a {
  display: inline-block; text-decoration: none;
  background: none; border: 1px solid transparent; border-radius: 999px;
  padding: 6px 12px; font: 600 .85rem/1 var(--mono); letter-spacing: .06em; color: var(--soft);
}
.langs a:hover { color: var(--ink); }
.langs a[aria-current="page"] { color: var(--ink); border-color: var(--line); }

/* First screen: header + password + options fill exactly one screen, so the
   line under "Make it fit" is the fold. Spare height goes around the password. */
.fold { min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; }
.fold main { flex: 1 1 auto; display: flex; flex-direction: column; }
.hero { flex: 1 1 auto; display: flex; flex-direction: column; align-items: center; padding-bottom: 28px; text-align: center; }
.hero-main { flex: 1 1 auto; width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; padding-block: 8px 12px; }
.stage { width: 100%; overflow: hidden; }
.pw {
  display: inline-block; white-space: nowrap; cursor: copy;
  font-family: var(--display); font-weight: 800; font-stretch: 100%;
  font-size: min(15vw, 17vh, 10.5rem); line-height: 1.05; letter-spacing: -.015em;
  user-select: all; -webkit-user-select: all; padding: .06em .08em; border-radius: .08em;
  font-variant-numeric: lining-nums;
}
/* Phones stack one word per line (the stage is under 520px wide here). It's
   CSS, not script, so the sample in the HTML is already stacked on first
   paint and swapping in the real password doesn't move the page. */
@media (max-width: 565px) {
  .pw { font-size: min(25vw, 12svh); line-height: .98; text-align: left; }
  .pw .g { display: block; }
}
.pw .sep, .pw .num { color: var(--accent); }
.pw .sep { font-weight: 500; }
.pw.pop { animation: pop .42s cubic-bezier(.2, .9, .3, 1.3); }
@keyframes pop { 0% { transform: scale(.985); } 60% { transform: scale(1.012); } 100% { transform: none; } }

.status { margin: 14px 0 20px; font: 400 .95rem/1.4 var(--mono); color: var(--soft); min-height: 1.4em; }
.status.ok #statusText { color: var(--accent); }
.status.ok #statusText::before { content: '✓ '; }

.actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; }
.btn {
  display: inline-flex; align-items: center; gap: 10px; min-height: 52px;
  padding: 0 22px; border-radius: 999px; border: 2px solid var(--ink); background: transparent;
  font-weight: 700; font-size: 1.02rem; transition: transform .12s ease, background-color .12s ease;
}
.btn svg { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.btn:hover { background: rgba(246, 244, 239, .1); }
.btn:active { transform: scale(.97); }
.btn-primary { background: var(--ink); color: var(--field); }
.btn-primary:hover { background: #fff; }
.checks { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 18px; font: 400 .9rem/1.4 var(--mono); color: var(--soft); }
.checks i { font-style: normal; color: var(--accent); font-weight: 600; }
.checks li.off { opacity: .5; }
.checks li.off i { color: var(--soft); }
.tests { margin: 14px 0 0; font-size: .92rem; color: var(--soft); }
.tests a { color: var(--soft); text-underline-offset: 3px; margin-left: 10px; white-space: nowrap; }
.tests a:hover { color: var(--accent); }
kbd { font: 600 .72rem/1 var(--mono); padding: 4px 7px; border: 1px solid var(--line); border-radius: 6px; color: var(--soft); }

/* Options */
.options { border-top: 1px solid var(--line); padding-block: 26px; }
.opt-head { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; margin-bottom: 20px; }
.eyebrow { margin: 0; font: 600 .78rem/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--soft); }
.opt-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 28px 40px; }
.opt { border: 0; margin: 0; padding: 0; min-width: 0; }
.opt legend { padding: 0; margin-bottom: 12px; font: 700 1.3rem/1.2 var(--display); font-stretch: 115%; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  min-width: 44px; min-height: 44px; padding: 0 14px; border-radius: 999px;
  background: var(--field-deep); border: 1px solid var(--line); font: 600 1rem/1 var(--mono);
}
.chip:hover { border-color: var(--soft); }
.chip:disabled { opacity: .35; cursor: not-allowed; border-color: var(--line); }
/* ? (to its FAQ answer) and ▶ (the film) before "Make it memorable", so the label ends flush right. */
.memo-icons { display: inline-flex; gap: .5em; vertical-align: .05em; white-space: nowrap; }
.info, .play {
  position: relative; display: inline-grid; place-items: center; width: 1.6em; height: 1.6em; padding: 0; border-radius: 50%;
  border: 1.5px solid var(--soft); background: none; color: var(--soft); font: 700 .62em/1 var(--mono); text-decoration: none; cursor: pointer;
}
.play svg { width: .7em; height: .7em; fill: currentColor; margin-left: .1em; }
.info::after, .play::after { content: ''; position: absolute; inset: -8px; } /* bigger tap target */
.info:hover, .play:hover, .info:focus-visible, .play:focus-visible { color: var(--ink); border-color: var(--ink); }
.watch { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 18px; border-radius: 999px; border: 1.5px solid var(--accent); background: none; color: var(--accent); font: 600 1rem/1 var(--body); cursor: pointer; }
.watch svg { fill: currentColor; }
.watch:hover { background: var(--accent); color: var(--field); }
dialog.video { padding: 0; border: 0; background: #000; width: min(92vw, calc(88vh * 16 / 9)); max-width: none; border-radius: 14px; overflow: hidden; }
dialog.video::backdrop { background: rgba(5, 5, 30, .82); }
dialog.video video { display: block; width: 100%; height: auto; }
dialog.video .close { position: absolute; top: 10px; right: 10px; min-height: 36px; padding: 0 14px; border-radius: 999px; border: 0; background: rgba(0, 0, 0, .55); color: #fff; font: 600 .9rem/1 var(--body); cursor: pointer; }
.chip[aria-pressed="true"], .chip[aria-checked="true"] { background: var(--ink); color: var(--field); border-color: var(--ink); }
.field {
  min-height: 44px; border-radius: 12px; border: 1px solid var(--line); background: var(--field-deep);
  color: var(--ink); font: 600 1.1rem/1 var(--mono); padding: 0 12px;
}
.field::placeholder { color: var(--soft); opacity: .7; font-weight: 400; font-size: .95rem; }
.field:focus { outline: none; border-color: var(--accent); }
.field-sep { width: 5.2em; min-width: 44px; border-radius: 999px; text-align: center; }
.field-sep.on { background: var(--ink); color: var(--field); border-color: var(--ink); }
/* Two digits, no more: sized to the digits, shaped like the chips beside it. */
.field-max { width: calc(2ch + 30px); padding: 0 14px; border-radius: 999px; text-align: center; font-variant-numeric: tabular-nums; }
.hint { margin: 10px 0 0; font-size: .9rem; color: var(--accent); }
.error { margin: 24px 0 0; padding: 12px 16px; border-left: 3px solid var(--accent); background: var(--field-deep); }

/* Comparison: what other generators hand out by default, next to ours */
.cmp { border-top: 1px solid var(--line); padding-block: 44px 20px; display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px 64px; }
.cmp h2 { margin: 0 0 10px; font: 700 clamp(1.4rem, 2.6vw, 1.9rem)/1.15 var(--display); font-stretch: 112%; letter-spacing: -.01em; }
.cmp h2, .pm h2 { text-wrap: balance; }
.cmp p { margin: 0; color: var(--soft); text-wrap: balance; }
.cmp-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.cmp-list li { display: grid; grid-template-columns: 8.5rem minmax(0, 1fr) auto; align-items: center; gap: 4px 20px; padding: 16px 0; border-bottom: 1px solid var(--line); }
.cmp .who { font: 600 .78rem/1.2 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--soft); }
.cmp code { font: 500 1.2rem/1.3 var(--mono); letter-spacing: .03em; color: var(--soft); overflow-wrap: anywhere; }
.cmp code i { font-style: normal; color: var(--accent); }
.cmp .how { display: grid; text-align: right; gap: 2px; }
.cmp .n { font: 400 .85rem/1.2 var(--mono); color: var(--soft); }
.cmp .n b { font-weight: 700; font-size: 1rem; color: var(--ink); }
.cmp .kind { font: 400 .78rem/1.2 var(--mono); color: var(--soft); }
.cmp .ours { border-bottom: 0; margin-top: 10px; padding: 22px 20px; background: var(--field-deep); border: 1px solid var(--accent); border-radius: 14px; }
.cmp .ours { grid-template-columns: minmax(0, 1fr) auto; }
.cmp .ours .who { grid-column: 1 / -1; color: var(--ink); }
.cmp .ours code { font: 700 clamp(1.7rem, 3.6vw, 2.5rem)/1.1 var(--display); font-stretch: 100%; letter-spacing: 0; color: var(--ink); }
.cmp .ours .sep, .cmp .ours .num { color: var(--accent); }
/* Wide screens: the four defaults sit two by two, ours spans the row below. */
@media (min-width: 900px) {
  .cmp-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 48px; }
  .cmp-list li { grid-template-columns: minmax(0, 1fr) auto; }
  .cmp .who { grid-column: 1 / -1; }
  .cmp-list .ours { grid-column: 1 / -1; }
}
@media (max-width: 720px) {
  .cmp-list li { grid-template-columns: minmax(0, 1fr) auto; }
  .cmp .who { grid-column: 1 / -1; }
  .cmp .ours { padding: 18px 16px; }
}

/* Password manager */
.pm { border-top: 1px solid var(--line); padding-block: 44px 20px; display: grid; grid-template-columns: minmax(0, 1fr); gap: 28px; }
.pm h2 { margin: 0 0 10px; font: 700 clamp(1.4rem, 2.6vw, 1.9rem)/1.15 var(--display); font-stretch: 112%; letter-spacing: -.01em; }
.pm p { margin: 0; color: var(--soft); text-wrap: balance; }
.pm-intro p + p { margin-top: 12px; }
.pm-intro a { color: var(--ink); text-decoration-color: var(--accent); text-underline-offset: 4px; }
.pm-steps { list-style: none; margin: 0; padding: 0; counter-reset: pm; display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 16px; }
.pm-steps li { counter-increment: pm; padding: 20px; background: var(--field-deep); border: 1px solid var(--line); border-radius: 14px; }
.pm-steps li::before { content: counter(pm); display: block; margin-bottom: 8px; font: 700 1.6rem/1 var(--display); color: var(--accent); }
.pm-steps h3 { margin: 0 0 6px; font: 700 1.1rem/1.25 var(--display); }
.pm-steps p { font-size: .95rem; text-wrap: pretty; }
.pm-apps ul { list-style: none; margin: 14px 0 0; padding: 0; border-top: 1px solid var(--line); }
.pm-apps li { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 2px 20px; padding: 14px 0; border-bottom: 1px solid var(--line); }
.pm-apps li a { font: 600 1.05rem/1.3 var(--display); color: var(--ink); text-decoration-color: var(--accent); text-underline-offset: 4px; }
.pm-apps li span { font: 400 .85rem/1.3 var(--mono); color: var(--soft); }
@media (min-width: 720px) {
  .pm-apps ul { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 48px; }
}
.pm .fine { margin-top: 14px; font: 400 .8rem/1.4 var(--mono); }

/* Film: poster with a big play button, above the footer */
.vid { border-top: 1px solid var(--line); padding-block: 44px 56px; }
.vid h2 { margin: 0 0 10px; font: 700 clamp(1.4rem, 2.6vw, 1.9rem)/1.15 var(--display); font-stretch: 112%; letter-spacing: -.01em; text-wrap: balance; }
.vid p { margin: 0 0 24px; color: var(--soft); text-wrap: balance; }
.vid-card { position: relative; display: block; width: 100%; max-width: 880px; padding: 0; overflow: hidden; border: 1px solid var(--line); border-radius: 14px; background: var(--field-deep); }
.vid-card img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; }
.vid-play { position: absolute; inset: 0; margin: auto; display: grid; place-items: center; width: 84px; height: 84px; border-radius: 50%; background: var(--ink); color: var(--field); transition: transform .15s ease, background-color .15s ease; }
.vid-play svg { fill: currentColor; margin-left: 4px; }
.vid-card:hover .vid-play { transform: scale(1.08); background: #fff; }
@media (prefers-reduced-motion: reduce) { .vid-play { transition: none; } }

/* About / SEO */
.about { border-top: 1px solid var(--line); padding-block: 44px 56px; display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px 64px; }
.about h2 { margin: 0 0 10px; font: 700 clamp(1.4rem, 2.6vw, 1.9rem)/1.15 var(--display); font-stretch: 112%; letter-spacing: -.01em; }
.about p { margin: 0 0 30px; color: var(--soft); max-width: 58ch; text-wrap: pretty; }
details { border-bottom: 1px solid var(--line); }
details:first-of-type { border-top: 1px solid var(--line); }
summary { cursor: pointer; padding: 16px 28px 16px 0; font-weight: 700; list-style: none; position: relative; }
summary::-webkit-details-marker { display: none; }
summary::after { content: '+'; position: absolute; right: 4px; top: 12px; font: 400 1.5rem/1 var(--mono); color: var(--accent); }
details[open] summary::after { content: '−'; }
details p { margin: 0 0 18px; }

.foot { border-top: 1px solid var(--line); padding-block: 22px 28px; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 24px; font: 400 .85rem/1.4 var(--mono); color: var(--soft); }

/* Wide screens: five tools across the row; the first sits left, the last right,
   the middle three centered in the space between. */
@media (min-width: 1240px) {
  .opt-grid { grid-template-columns: repeat(5, auto); justify-content: space-between; column-gap: 24px; }
  .chips { flex-wrap: nowrap; }
  /* Titles may take two lines (all but "Between words"). The legend keeps a
     one-line box, so the gap under "Make it fit" doesn't move; a second line
     grows upward from the bottom-aligned text. */
  .opt:not(:first-child) { min-width: 9rem; }
  .opt legend { position: relative; width: 100%; height: 1.2em; font-size: 1.15rem; }
  .opt legend > span { position: absolute; left: 0; right: 0; bottom: 0; }
  .opt:first-child legend > span { white-space: nowrap; }
  .opt:nth-child(n+2):nth-child(-n+4) { text-align: center; }
  .opt:nth-child(n+2):nth-child(-n+4) .chips { justify-content: center; }
  .opt:nth-child(5) { text-align: right; }
  /* Room for the last word plus ? and ▶, so the icons never sit alone on a line. */
  .opt:nth-child(5) { min-width: 12rem; }
  .opt:nth-child(5) .chips { justify-content: flex-end; }
}

/* Phones: the first screen is the password alone (header + hero); the
   options start below the fold. 72px is the header's height. */
@media (max-width: 640px) {
  .fold { min-height: 0; }
  .hero { min-height: calc(100vh - 72px); min-height: calc(100svh - 72px); }
}

@media (max-width: 560px) {
  .btn { flex: 1 1 auto; justify-content: center; }
  kbd { display: none; }
  /* The four testers on one row under the question. */
  .tests { width: 100%; }
  .test-links { display: flex; justify-content: space-between; margin-top: 6px; }
  .tests a { margin-left: 0; font-size: .82rem; }
}
@media (prefers-reduced-motion: reduce) {
  .pw.pop { animation: none; }
  .btn { transition: none; }
}
.foot a { color: inherit; text-decoration: none; }
.foot a:hover { color: var(--ink); text-decoration: underline; }
