/* =========================================================================================
   frizzy-g.com, "Night": the default look (Neon Afterglow), the same family as Mbao's and
   Stretcher's Night. A deep indigo sky with three soft lights drifting behind everything (violet,
   magenta, cyan), the name lit up like a neon sign over a strip of holographic foil with the two
   glossy balls on its ends, and a glass card per app with a neon edge, its own light and a little
   drawn emblem. The sunset gradient marks the one thing to press: each card's go button.

   Hand-written, phone first at 390px. Tokens first. System fonts only (the CSP allows no web
   fonts); the emblems and icons are data: SVGs, which the CSP allows. Loops move transform and
   opacity (plus background-position on two small things: the foil and the glint); no animated
   blur, no backdrop-filter. Everything stops under prefers-reduced-motion and the page still
   looks finished. The look's script (night.js) turns it up and only adds the nfx- classes at the
   end of this file: the page above them is complete without it.
   ========================================================================================= */

:root {
  color-scheme: dark;

  /* ground and surfaces: a deep indigo night, never neutral grey */
  --bg: #0a0820;
  --surface: rgba(25, 19, 60, .76);
  --surface-solid: #17123b;
  --sunk: rgba(6, 3, 24, .5);

  /* text: each passes 4.5:1 on the brightest thing it can sit on (glows included) */
  --text: #f7f4ff;
  --text-2: #d4cff0;
  --text-3: #c0b9e2;

  /* the neon, and light versions of it that are safe as text on the dark */
  --pink: #ff4fa3;
  --pink-soft: #ffb6dc;
  --violet: #8b6cff;
  --violet-soft: #d0c2ff;
  --cyan: #2fe5ef;
  --cyan-soft: #98f3f8;
  --amber: #ffb547;
  --ink: #1c0f26;                  /* text and icons on the sunset */

  --sunset: linear-gradient(112deg, #ff3f9b 0%, #ff5d82 30%, #ff8760 64%, #ffba4b 100%);
  --glint: linear-gradient(105deg, rgba(255, 255, 255, 0) 41%, rgba(255, 255, 255, .55) 50%, rgba(255, 255, 255, 0) 59%);
  /* holographic foil: two turns of pink, peach, mint, sky and lilac, so a full rainbow always shows */
  --foil: linear-gradient(90deg, #ffb6dc 0%, #ffd4bb 10%, #c0ffdb 20%, #b5eeff 30%, #cbbbff 40%, #ffb6dc 50%, #ffd4bb 60%, #c0ffdb 70%, #b5eeff 80%, #cbbbff 90%, #ffb6dc 100%);
  --luminous: linear-gradient(100deg, #ffffff 0%, #fff0f8 34%, #ffb3da 68%, #c9b8ff 100%);
  --grad-card: linear-gradient(180deg, rgba(255, 255, 255, .07), rgba(255, 255, 255, .015) 64%);

  --rim: inset 0 1px 0 rgba(255, 255, 255, .09), inset 0 0 0 1px rgba(214, 200, 255, .085);
  --lift: 0 1px 2px rgba(0, 0, 0, .35), 0 16px 36px -18px rgba(4, 0, 24, .9);
  --bevel: inset 0 1px 0 rgba(255, 255, 255, .55), inset 0 -2px 0 rgba(120, 20, 50, .16);

  --r-l: 24px;
  --gutter: 16px;
  --focus: #ffffff;

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI", system-ui, Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI Variable Display", "Segoe UI", system-ui, Roboto, "Helvetica Neue", Arial, sans-serif;

  --ease: cubic-bezier(.2, .8, .2, 1);
  --spring: cubic-bezier(.34, 1.45, .64, 1);

  /* the go arrow, in ink (it sits on the sunset) */
  --i-go: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 8h9.2M8.6 3.8 12.8 8l-4.2 4.2' fill='none' stroke='%231c0f26' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  /* the emblems, drawn like the apps' own marks (glossy balls lit from the top left) */
  --e-mbao: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 56 56'%3E%3Cdefs%3E%3CradialGradient id='p' cx='.34' cy='.28' r='.78'%3E%3Cstop offset='0' stop-color='%23fff'/%3E%3Cstop offset='.14' stop-color='%23ffd2ea'/%3E%3Cstop offset='.52' stop-color='%23ff4fa3'/%3E%3Cstop offset='1' stop-color='%23a8125c'/%3E%3C/radialGradient%3E%3CradialGradient id='c' cx='.34' cy='.28' r='.78'%3E%3Cstop offset='0' stop-color='%23fff'/%3E%3Cstop offset='.14' stop-color='%23d2fdff'/%3E%3Cstop offset='.52' stop-color='%232fe5ef'/%3E%3Cstop offset='1' stop-color='%230b7894'/%3E%3C/radialGradient%3E%3CradialGradient id='g'%3E%3Cstop offset='0' stop-color='%23fff' stop-opacity='.5'/%3E%3Cstop offset='1' stop-color='%23fff' stop-opacity='0'/%3E%3C/radialGradient%3E%3C/defs%3E%3Ccircle cx='19' cy='29' r='15' fill='%23ff4fa3' opacity='.22'/%3E%3Ccircle cx='37.5' cy='29' r='15' fill='%232fe5ef' opacity='.18'/%3E%3Ccircle cx='19.5' cy='29' r='10.5' fill='url%28%23p%29'/%3E%3Ccircle cx='37' cy='29' r='10.5' fill='url%28%23c%29'/%3E%3Cellipse cx='28' cy='44' rx='17' ry='2.4' fill='url%28%23g%29' opacity='.5'/%3E%3C/svg%3E");
  --e-stretcher: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 56 56'%3E%3Cdefs%3E%3CradialGradient id='p' cx='.34' cy='.28' r='.78'%3E%3Cstop offset='0' stop-color='%23fff'/%3E%3Cstop offset='.14' stop-color='%23ffd2ea'/%3E%3Cstop offset='.52' stop-color='%23ff4fa3'/%3E%3Cstop offset='1' stop-color='%23a8125c'/%3E%3C/radialGradient%3E%3CradialGradient id='c' cx='.34' cy='.28' r='.78'%3E%3Cstop offset='0' stop-color='%23fff'/%3E%3Cstop offset='.14' stop-color='%23d2fdff'/%3E%3Cstop offset='.52' stop-color='%232fe5ef'/%3E%3Cstop offset='1' stop-color='%230b7894'/%3E%3C/radialGradient%3E%3ClinearGradient id='b' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='%23ff4fa3'/%3E%3Cstop offset='.5' stop-color='%23b07cff'/%3E%3Cstop offset='1' stop-color='%232fe5ef'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M14 34 C22 22 34 22 42 34' fill='none' stroke='url%28%23b%29' stroke-width='3' stroke-linecap='round' opacity='.95'/%3E%3Ccircle cx='13' cy='35' r='12' fill='%23ff4fa3' opacity='.2'/%3E%3Ccircle cx='43' cy='35' r='12' fill='%232fe5ef' opacity='.18'/%3E%3Ccircle cx='13' cy='35' r='7.5' fill='url%28%23p%29'/%3E%3Ccircle cx='43' cy='35' r='7.5' fill='url%28%23c%29'/%3E%3C/svg%3E");
  --e-earshot: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 56 56'%3E%3Cdefs%3E%3CradialGradient id='v' cx='.34' cy='.28' r='.78'%3E%3Cstop offset='0' stop-color='%23fff'/%3E%3Cstop offset='.14' stop-color='%23e6ddff'/%3E%3Cstop offset='.55' stop-color='%238b6cff'/%3E%3Cstop offset='1' stop-color='%234a2fc9'/%3E%3C/radialGradient%3E%3C/defs%3E%3Ccircle cx='20' cy='28' r='14' fill='%238b6cff' opacity='.24'/%3E%3Ccircle cx='20' cy='28' r='9.5' fill='url%28%23v%29'/%3E%3Cg fill='none' stroke-linecap='round'%3E%3Cpath d='M34 21.5a9.5 9.5 0 0 1 0 13' stroke='%2398f3f8' stroke-width='2.6'/%3E%3Cpath d='M39.5 17a16 16 0 0 1 0 22' stroke='%232fe5ef' stroke-width='2.4' opacity='.8'/%3E%3Cpath d='M45 12.5a22.5 22.5 0 0 1 0 31' stroke='%232fe5ef' stroke-width='2.2' opacity='.45'/%3E%3C/g%3E%3C/svg%3E");
  /* the padlock on the PIN badge (a mask: it takes the badge's colour) */
  --i-lock: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 12'%3E%3Cpath d='M2.6 5.2V3.7a2.4 2.4 0 0 1 4.8 0v1.5' fill='none' stroke='%23000' stroke-width='1.6'/%3E%3Crect x='.8' y='5' width='8.4' height='6.4' rx='1.6'/%3E%3C/svg%3E");
  /* film grain in the sky, so the big gradients never band */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .07 0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url%28%23g%29'/%3E%3C/svg%3E");
}

/* a real spring where the browser can do one */
@supports (transition-timing-function: linear(0, 1)) {
  :root { --spring: linear(0, .12 4%, .44 10%, .79 17%, .98 23%, 1.05 28%, 1.06 32%, 1.04 38%, 1.01 46%, .995 56%, 1); }
}

/* ---------- base ---------- */

*, *::before, *::after { box-sizing: border-box; }
html {
  background: var(--bg);
  -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
}
body {
  margin: 0; min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; justify-content: center;
  color: var(--text); font: 400 16px/1.5 var(--font);
  overflow-x: clip;
}
::selection { background: rgba(255, 79, 163, .42); color: #fff; }
:focus-visible { outline: 2.5px solid var(--focus); outline-offset: 3px; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* the sky: deep indigo, a little lighter overhead, with a fine grain (it shows through the lights) */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background:
    var(--grain),
    radial-gradient(120% 55% at 50% -12%, rgba(78, 52, 178, .3), rgba(78, 52, 178, 0) 70%),
    radial-gradient(100% 50% at 50% 118%, rgba(48, 22, 120, .42), rgba(48, 22, 120, 0) 70%),
    linear-gradient(180deg, #0d0a29 0%, #0a0820 50%, #08061a 100%);
}

/* the living background (.ambient, three <i>): three big soft lights drifting slowly. Radial
   gradients that fade to nothing at their edge, moved with transform only, in ten small steps a
   second (they creep a few pixels a second: nobody sees the steps, and the screen isn't
   recomposited sixty times a second). --s is the size, --x/--y the centre */
.ambient { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.ambient i {
  position: absolute; display: block; border-radius: 50%;
  width: var(--s); height: var(--s); left: calc(var(--x) - var(--s) / 2); top: calc(var(--y) - var(--s) / 2);
}
.ambient i:nth-child(1) { /* violet, overhead on the left */
  --s: 118vw; --x: 0vw; --y: -4vh;
  background: radial-gradient(closest-side, rgba(124, 82, 255, .38), rgba(124, 82, 255, .15) 55%, rgba(124, 82, 255, 0));
  animation: nfx-drift-a 38s steps(380) infinite alternate;
}
.ambient i:nth-child(2) { /* magenta, coming in from the right */
  --s: 112vw; --x: 102vw; --y: 40vh;
  background: radial-gradient(closest-side, rgba(255, 52, 160, .3), rgba(255, 52, 160, .11) 55%, rgba(255, 52, 160, 0));
  animation: nfx-drift-b 46s steps(460) infinite alternate;
}
.ambient i:nth-child(3) { /* cyan, low down */
  --s: 118vw; --x: -4vw; --y: 90vh;
  background: radial-gradient(closest-side, rgba(30, 214, 235, .2), rgba(30, 214, 235, .075) 55%, rgba(30, 214, 235, 0));
  animation: nfx-drift-c 54s steps(540) infinite alternate;
}

/* ---------- layout ---------- */

/* the name, the cards and the switch sit together in the middle of the screen */
.home {
  width: 100%; max-width: 560px; margin: 0 auto;
  display: flex; flex-direction: column; gap: 34px;
  padding: max(30px, calc(env(safe-area-inset-top) + 18px)) max(var(--gutter), env(safe-area-inset-right)) 0 max(var(--gutter), env(safe-area-inset-left));
}

/* ---------- the name, lit up like a sign ---------- */

/* a kicker over it (a live dot and "Open all night"), then the name over a strip of foil */
.logo {
  margin: 0; display: grid; grid-template-columns: 1fr auto auto 1fr; align-items: center;
  column-gap: 10px; row-gap: 14px; text-align: center;
}
.logo::before { /* the live dot: it's on */
  content: ""; grid-row: 1; grid-column: 2; width: 8px; height: 8px; border-radius: 50%;
  background: var(--pink); box-shadow: 0 0 10px rgba(255, 79, 163, .95), 0 0 0 0 rgba(255, 110, 180, .7);
  animation: nfx-ping 2.4s var(--ease) infinite;
}
.logo::after {
  content: "Open all night"; content: "Open all night" / "";
  grid-row: 1; grid-column: 3;
  font: 750 12px/1.2 var(--font); letter-spacing: .2em; text-transform: uppercase; color: var(--pink-soft);
}
.logo-img { display: none; }
.logo-text {
  grid-row: 2; grid-column: 1 / -1; justify-self: center; position: relative;
  display: block; padding: 0 .06em .5em .02em;
  font: italic 850 clamp(54px, 18.6vw, 84px)/1 var(--font-display); letter-spacing: -.035em; white-space: nowrap;
  color: var(--text);
  background: var(--glint) 160% 0 / 250% 100% no-repeat, var(--luminous);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 0 20px rgba(255, 79, 163, .34)) drop-shadow(0 0 2px rgba(255, 220, 240, .35));
  animation: nfx-shine 7s ease-in-out 2.2s infinite;
}
/* under it, as under the picture logo: a bar. Here it's a band of holographic foil with the two
   glossy balls on its ends (the apps' mark), drawn as one masked strip so it scales with the name,
   and behind the y's tail, as in the picture */
.logo-text::after {
  content: ""; position: absolute; z-index: -1; left: 3%; right: 4%; bottom: 0; height: 18px;
  background:
    radial-gradient(circle at 34% 28%, #ffffff 0, #ffd2ea 14%, #ff4fa3 52%, #a8125c 100%) left center / 18px 18px no-repeat,
    radial-gradient(circle at 34% 28%, #ffffff 0, #d2fdff 14%, #2fe5ef 52%, #0b7894 100%) right center / 18px 18px no-repeat,
    var(--foil) 0 50% / 200% 6px repeat-x;
  -webkit-mask:
    radial-gradient(circle 9px at 9px 50%, #000 8.5px, transparent 9px),
    radial-gradient(circle 9px at calc(100% - 9px) 50%, #000 8.5px, transparent 9px),
    linear-gradient(#000 0 0) center / calc(100% - 20px) 6px no-repeat;
  mask:
    radial-gradient(circle 9px at 9px 50%, #000 8.5px, transparent 9px),
    radial-gradient(circle 9px at calc(100% - 9px) 50%, #000 8.5px, transparent 9px),
    linear-gradient(#000 0 0) center / calc(100% - 20px) 6px no-repeat;
  animation: nfx-foil 9s ease-in-out infinite alternate;
}
/* the sign's light on the haze behind it: pink under the name, the band's ends glowing pink and cyan.
   Every ellipse fades out well inside the layer, so it has no edges */
.logo-text::before {
  content: ""; position: absolute; left: -14%; right: -14%; top: -30%; bottom: -36%; z-index: -2; pointer-events: none;
  background:
    radial-gradient(.62em .34em at 14.5% 75%, rgba(255, 79, 163, .3), rgba(255, 79, 163, 0)),
    radial-gradient(.62em .34em at 85.5% 75%, rgba(47, 229, 239, .24), rgba(47, 229, 239, 0)),
    radial-gradient(42% 38% at 50% 48%, rgba(190, 70, 200, .2), rgba(190, 70, 200, 0));
}

/* ---------- the apps: glass cards, each with its own light ---------- */

.apps { display: flex; flex-direction: column; gap: 14px; }
.app {
  --accent: 255, 79, 163; --accent-2: 255, 181, 71; --soft: #ffc2e2;
  --emblem: var(--e-mbao);
  position: relative; isolation: isolate;
  display: grid; grid-template-columns: 64px minmax(0, 1fr); grid-template-rows: auto auto;
  column-gap: 18px; row-gap: 0; align-items: center;
  min-height: 110px; padding: 18px 18px 18px 18px; border-radius: var(--r-l);
  color: var(--text); text-decoration: none; -webkit-tap-highlight-color: transparent;
  background:
    radial-gradient(110% 120% at 0% 0%, rgba(var(--accent), .2), rgba(var(--accent), 0) 58%),
    radial-gradient(90% 120% at 100% 100%, rgba(var(--accent-2), .09), rgba(var(--accent-2), 0) 60%),
    var(--grad-card), var(--surface);
  box-shadow: 0 24px 46px -26px rgba(var(--accent), .62), var(--lift);
  transition: transform .5s var(--spring), box-shadow .3s var(--ease);
}
.app-mbao { --accent: 255, 79, 163; --accent-2: 255, 181, 71; --soft: #ffc2e2; --emblem: var(--e-mbao); }
.app-stretcher { --accent: 168, 139, 255; --accent-2: 255, 79, 163; --soft: #d9ceff; --emblem: var(--e-stretcher); }
.app-earshot { --accent: 47, 229, 239; --accent-2: 139, 108, 255; --soft: #b4f6fa; --emblem: var(--e-earshot); }
/* the neon edge: a gradient ring, a full-size layer masked down to its 1.5px rim */
.app::after {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; padding: 1.5px; pointer-events: none;
  background: linear-gradient(150deg, rgba(var(--accent), .95), rgba(139, 108, 255, .42) 40%, rgba(255, 255, 255, .07) 66%, rgba(var(--accent-2), .5));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}
/* the emblem: a little glass tile with the app's mark drawn in it */
.app::before {
  content: ""; grid-column: 1; grid-row: 1 / span 2; width: 64px; height: 64px; border-radius: 20px;
  background:
    var(--emblem) center / 64px 64px no-repeat,
    radial-gradient(90% 80% at 30% 15%, rgba(255, 255, 255, .13), rgba(255, 255, 255, 0) 70%),
    linear-gradient(160deg, #261d5c, #130e33);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .14), inset 0 0 0 1px rgba(214, 200, 255, .13), 0 10px 22px -10px rgba(var(--accent), .8);
  transition: transform .55s var(--spring);
}
/* the name is all a card says now (George: "only app titles"), so it's big; it runs the width of
   the card and carries the go button at its right-hand end */
.app-name {
  grid-column: 2; grid-row: 1 / span 2; align-self: center; position: relative; padding-right: 58px;
  font: 780 34px/1.1 var(--font-display); letter-spacing: -.028em; color: var(--text);
  background: linear-gradient(100deg, #ffffff 30%, var(--soft) 100%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
/* the go button: the one sunset thing on each card (decoration: the whole card is the link), at the
   end of the name. A glint crosses it every few seconds, running down the cards in turn */
.app-name::after {
  content: ""; position: absolute; right: 0; top: 50%; width: 42px; height: 42px; margin-top: -21px; border-radius: 50%;
  background: var(--i-go) center / 18px 18px no-repeat, var(--glint) 160% 0 / 250% 100% no-repeat, var(--sunset);
  box-shadow: var(--bevel), 0 0 0 1px rgba(255, 110, 170, .35), 0 10px 22px -10px rgba(255, 79, 163, .85);
  transition: transform .5s var(--spring), box-shadow .3s var(--ease);
  animation: nfx-btnshine 5.5s ease-in-out 1.4s infinite;
}
.app-stretcher .app-name::after { animation-delay: 1.65s; }
.app-earshot .app-name::after { animation-delay: 1.9s; }
/* PIN: the friends-only apps (George's PIN, see pin\README.md). A little glass tag hanging off the
   bottom of the emblem: a padlock and the word, in the card's own colour. It's real text, so a
   screen reader says it with the app's name */
.app-lock {
  grid-column: 1; grid-row: 1 / span 2; align-self: center; justify-self: center; z-index: 1;
  display: inline-flex; align-items: center; gap: 3px; height: 19px; padding: 0 7px 0 6px; border-radius: 999px;
  font: 800 10.5px/1 var(--font); letter-spacing: .12em; color: var(--soft); white-space: nowrap;
  background: linear-gradient(180deg, rgba(255, 255, 255, .1), rgba(255, 255, 255, 0)), #140e36;
  box-shadow: inset 0 0 0 1px rgba(var(--accent), .7), 0 0 12px -3px rgba(var(--accent), .75), 0 4px 10px -4px rgba(0, 0, 0, .8);
  transform: translateY(27px); /* centred where the emblem is, then down to its bottom edge (below) */
  pointer-events: none;
}
.app-lock::before {
  content: ""; flex: none; width: 8px; height: 10px; margin-top: -1px; background: currentColor;
  -webkit-mask: var(--i-lock) center / contain no-repeat; mask: var(--i-lock) center / contain no-repeat;
}
/* a locked card's emblem sits 5px higher, so the emblem and its tag are centred together */
.app-locked::before { margin-bottom: 10px; }
@media (hover: hover) {
  .app:hover { transform: translateY(-2px); box-shadow: 0 30px 56px -24px rgba(var(--accent), .8), var(--lift); }
  .app:hover::before { transform: scale(1.06) rotate(-3deg); }
  .app:hover .app-name::after { transform: translateX(3px); box-shadow: var(--bevel), 0 0 0 1px rgba(255, 110, 170, .5), 0 12px 26px -8px rgba(255, 79, 163, .95); }
}
.app:active { transform: scale(.975); transition-duration: .12s, .3s; }
.app:focus-visible { outline: 2.5px solid var(--focus); outline-offset: 4px; }

/* ---------- footer: the look switch (a sunk track; the look that's on raised in glass) ---------- */

/* the pill is the track, the label floats over it, and the buttons sit in whatever order the
   page lists them (it's the order Tab takes, so it has to be the order you see) */
.foot { display: flex; justify-content: center; padding: 62px var(--gutter) calc(30px + 3vh + env(safe-area-inset-bottom)); }
.look-pick {
  position: relative; display: inline-flex; align-items: center; gap: 4px; padding: 4px; border-radius: 999px;
  background: var(--sunk); box-shadow: inset 0 1px 3px rgba(0, 0, 0, .5), inset 0 0 0 1px rgba(214, 200, 255, .08);
}
.look-label {
  position: absolute; left: 50%; bottom: calc(100% + 13px); transform: translateX(-50%);
  font: 700 11px/1 var(--font); letter-spacing: .18em; text-transform: uppercase; color: var(--text-2); white-space: nowrap;
}
.look-opt {
  appearance: none; -webkit-appearance: none; position: relative; margin: 0; border: 0;
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 15px 0 12px; border-radius: 999px;
  background: transparent; color: var(--text-2); font: 600 14px/1 var(--font); white-space: nowrap;
  cursor: pointer; touch-action: manipulation; -webkit-tap-highlight-color: transparent;
  transition: background-color .25s var(--ease), color .2s var(--ease), transform .45s var(--spring);
}
@media (hover: hover) { .look-opt:hover { color: var(--text); } }
.look-opt:active { transform: scale(.95); }
.look-opt:focus-visible { outline-offset: 1px; }
/* each option shows a swatch of its look */
.look-opt::before { content: ""; flex: none; width: 14px; height: 14px; border-radius: 50%; }
.look-night::before { background: conic-gradient(from 210deg, #ff4fa3, #8b6cff, #2fe5ef, #ff4fa3); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .3); }
.look-frizzy::before { background: linear-gradient(135deg, #808080 0 50%, #55ff00 50% 100%); box-shadow: inset 0 0 0 1.5px #000, 0 0 0 1px rgba(255, 255, 255, .3); }
.look-tom::before { background: conic-gradient(from 20deg, #ff00d4, #ffe600, #00e5ff, #ff00d4); box-shadow: 0 0 0 1px rgba(255, 255, 255, .3); }
/* the look that's on: raised, bold, a ring round its swatch (not just a colour) */
.look-opt[aria-pressed="true"] {
  color: var(--text); font-weight: 700;
  background: linear-gradient(180deg, rgba(255, 255, 255, .15), rgba(255, 255, 255, .06)), #2a2166;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18), inset 0 0 0 1px rgba(255, 150, 210, .5), 0 4px 14px -2px rgba(0, 0, 0, .6), 0 0 20px -6px rgba(255, 79, 163, .6);
}
.look-opt[aria-pressed="true"]::before { box-shadow: 0 0 0 2px #2a2166, 0 0 0 3.5px rgba(255, 255, 255, .85); }

/* the look menu in the corner is lookmenu.css's, the same in every look on all the Frizzy G sites:
   .top-end, .corner, .look-menu, .look-burger, .look-panel, .look-panel-label, .lm-opts, .lm-opt,
   .lm-night, .lm-frizzy, .lm-tom, .lm-castle, and the Tom mode PIN form in it: .lm-pin, .lm-pin-label,
   .lm-pin-row, .lm-pin-input, .lm-pin-go, .lm-pin-wrong */

/* ---------- motion ---------- */

/* one-shot entrances: everything settles up into place with a short stagger, done inside ~0.8s.
   Transform only, filling backwards: content is readable from the first frame */
.logo { animation: nfx-drop .6s var(--ease) backwards; }
.app { animation: nfx-rise .6s var(--ease) .08s backwards; }
.app-stretcher { animation-delay: .14s; }
.app-earshot { animation-delay: .2s; }
.look-pick { animation: nfx-rise .6s var(--ease) .28s backwards; }

@keyframes nfx-rise { from { transform: translateY(18px); } }
@keyframes nfx-drop { from { transform: translateY(-10px); } }
@keyframes nfx-drift-a { to { transform: translate(32vw, 20vh) scale(1.1); } }
@keyframes nfx-drift-b { to { transform: translate(-36vw, 16vh) scale(.92); } }
@keyframes nfx-drift-c { to { transform: translate(40vw, -22vh) scale(1.08); } }
@keyframes nfx-ping {
  0% { box-shadow: 0 0 10px rgba(255, 79, 163, .95), 0 0 0 0 rgba(255, 110, 180, .75); }
  70%, 100% { box-shadow: 0 0 10px rgba(255, 79, 163, .95), 0 0 0 9px rgba(255, 110, 180, 0); }
}
@keyframes nfx-shine { 0% { background-position: 160% 0, 0 0; } 22%, 100% { background-position: -60% 0, 0 0; } }
@keyframes nfx-btnshine { 0% { background-position: center, 160% 0, 0 0; } 20%, 100% { background-position: center, -60% 0, 0 0; } }
@keyframes nfx-foil { from { background-position: left center, right center, 0 50%; } to { background-position: left center, right center, 100% 50%; } }

/* everything stops, and the page still looks finished */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
  .app:active, .look-opt:active { transform: none; }
}

/* ---------- sizes ---------- */

@media (max-width: 374px) {
  :root { --gutter: 12px; }
  .home { gap: 28px; }
  .app { grid-template-columns: 56px minmax(0, 1fr); column-gap: 14px; min-height: 98px; padding: 16px 14px; }
  .app::before { width: 56px; height: 56px; border-radius: 18px; background-size: 56px 56px, auto, auto; }
  .app-name { font-size: 31px; padding-right: 52px; }
  .app-name::after { width: 38px; height: 38px; margin-top: -19px; background-size: 17px 17px, 250% 100%, auto; }
  .app-lock { transform: translateY(23px); }
  .look-opt { gap: 6px; padding: 0 12px 0 10px; font-size: 13.5px; }
  .look-opt::before { width: 12px; height: 12px; }
}
@media (max-width: 330px) {
  .look-opt::before { display: none; }
  .look-opt { padding: 0 11px; }
}

/* a desktop: the name goes big across the top and the cards stand side by side under it */
@media (min-width: 900px) {
  :root { --gutter: 32px; }
  .home { max-width: 1160px; gap: 56px; padding-top: 56px; }
  .logo { row-gap: 18px; }
  .logo::after { font-size: 13px; }
  .logo-text { font-size: clamp(96px, 12.5vw, 176px); padding-bottom: .4em; }
  .logo-text::after { height: 26px; bottom: 2px;
    background-size: 26px 26px, 26px 26px, 200% 8px;
    -webkit-mask:
      radial-gradient(circle 13px at 13px 50%, #000 12.5px, transparent 13px),
      radial-gradient(circle 13px at calc(100% - 13px) 50%, #000 12.5px, transparent 13px),
      linear-gradient(#000 0 0) center / calc(100% - 28px) 8px no-repeat;
    mask:
      radial-gradient(circle 13px at 13px 50%, #000 12.5px, transparent 13px),
      radial-gradient(circle 13px at calc(100% - 13px) 50%, #000 12.5px, transparent 13px),
      linear-gradient(#000 0 0) center / calc(100% - 28px) 8px no-repeat;
  }
  /* three apps, three tall tiles side by side: the emblem up top, the name and its go button along
     the bottom */
  .apps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
  .app {
    grid-template-columns: minmax(0, 1fr); grid-template-rows: 1fr auto; row-gap: 0;
    align-items: start; min-height: 248px; padding: 28px 28px 30px; border-radius: 30px;
  }
  .app::before { grid-column: 1; grid-row: 1; width: 88px; height: 88px; border-radius: 26px; margin-bottom: 28px; background-size: 88px 88px, auto, auto; }
  .app-name { grid-column: 1; grid-row: 2; align-self: end; font-size: clamp(26px, 3.6vw - 6px, 42px); padding-right: 64px; }
  .app-name::after { width: 52px; height: 52px; margin-top: -26px; background-size: 22px 22px, 250% 100%, auto; }
  /* the tag hangs off the bottom of the emblem, centred under it */
  .app-lock { grid-row: 1; align-self: start; justify-self: start; height: 22px; padding: 0 9px 0 8px; font-size: 11.5px; transform: translate(calc(44px - 50%), 77px); }
  .foot { padding-top: 66px; }
}

/* big screens: the lights spread out into the margins */
@media (min-width: 1100px) {
  .ambient i:nth-child(1) { --s: 60vw; --x: 14vw; --y: 6vh; }
  .ambient i:nth-child(2) { --s: 52vw; --x: 92vw; --y: 42vh; }
  .ambient i:nth-child(3) { --s: 58vw; --x: 16vw; --y: 100vh; }
}

/* more contrast asked for: solid surfaces, crisper edges */
@media (prefers-contrast: more) {
  :root { --text-2: #e6e1fa; --text-3: #d2cced; --surface: #17123b; }
  .app::after { background: rgba(230, 220, 255, .7); }
  .look-pick { box-shadow: inset 0 0 0 1.5px rgba(230, 220, 255, .55); }
  .ambient { opacity: .6; }
}

/* Windows high contrast: keep every edge and state visible */
@media (forced-colors: active) {
  .app, .look-opt, .app-lock { border: 1px solid CanvasText; }
  .app-lock::before { background: CanvasText; }
  .ambient, body::before, .app::after, .logo-text::before { display: none; }
  .logo-text, .app-name { -webkit-text-fill-color: currentColor; background: none; filter: none; }
  .look-opt[aria-pressed="true"] { outline: 2px solid Highlight; }
}

/* =========================================================================================
   Effects. The look's script (night.js) adds the nfx- classes below while it runs: only on
   Night, only when motion is allowed, and it takes every one of them away again when the look
   changes. Without it none of them exist and everything above is the whole look.
   ========================================================================================= */

:root { --home-fx-night: on; } /* tells the script this sheet is live (the switch flips sheets late) */

/* the sky: a WebGL nebula drawn into the .ambient layer at under half resolution and scaled up.
   It fades in over the CSS lights, which then rest, and come straight back if the GPU drops it */
.nfx-sky { position: absolute; inset: 0; display: block; width: 100%; height: 100%; opacity: 0; transition: opacity .8s var(--ease); }
.nfx-sky.nfx-in { opacity: 1; }
.ambient.nfx-gl i { visibility: hidden; animation-play-state: paused; }

/* confetti, stars, glossy balls and sparks: one canvas over everything, only while something flies */
.nfx-burst { position: fixed; inset: 0; z-index: 30; display: block; width: 100%; height: 100%; pointer-events: none; }

/* 3D cards: the script turns the card every frame with a spring of its own, so the CSS transform
   transition steps aside; the glare is a layer it slides across the face */
.nfx-tilt { will-change: transform; transition: box-shadow .3s var(--ease); }
.nfx-sheen { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; pointer-events: none; opacity: 0; mix-blend-mode: screen; }
/* (soft enough that the words on the glass keep 4.5:1 even under a pressing finger) */
.nfx-sheen i {
  position: absolute; display: block; left: -50%; top: -50%; width: 200%; height: 200%;
  background: radial-gradient(closest-side, rgba(255, 244, 252, .2), rgba(255, 196, 236, .08) 40%, rgba(255, 196, 236, 0) 70%);
}

/* the names decode: an aria-hidden copy scrambles over the real text, which stays exactly where it
   is (just transparent), so screen readers only ever read the real name */
.nfx-decoding { position: relative; background: none; -webkit-text-fill-color: transparent; }
.nfx-decode {
  position: absolute; left: 0; top: 0; right: 0; padding: inherit; white-space: nowrap;
  pointer-events: none; -webkit-user-select: none; user-select: none;
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.logo-text > .nfx-decode { background-image: var(--luminous); }
/* (should an app's name ever take two lines on a narrow phone, the copy wraps just as it does) */
.app-name > .nfx-decode { white-space: normal; background-image: linear-gradient(100deg, #ffffff 30%, var(--soft) 100%); }
.nfx-decode .nfx-q { -webkit-text-fill-color: var(--cyan-soft); text-shadow: 0 0 12px rgba(47, 229, 239, .95), 0 0 2px rgba(47, 229, 239, .9); }
.nfx-decode .nfx-hit { animation: nfx-hit .5s var(--ease); }
@keyframes nfx-hit { from { -webkit-text-fill-color: var(--pink-soft); text-shadow: 0 0 16px #fff, 0 0 30px var(--pink); } }

/* a ripple from the finger, clipped to the card's (or the button's) shape */
.nfx-ripple { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; pointer-events: none; }
.nfx-ripple i { position: absolute; display: block; border-radius: 50%; background: radial-gradient(closest-side, rgba(255, 255, 255, .5), rgba(255, 255, 255, .18) 58%, rgba(255, 255, 255, 0)); }

@media (forced-colors: active) {
  .nfx-sky, .nfx-burst, .nfx-sheen, .nfx-ripple, .nfx-decode { display: none; }
  .nfx-decoding { -webkit-text-fill-color: currentColor; }
}
