/* =========================================================================================
   frizzy-g.com, "Frizzy G": the brand look, hand-made (23 Oct 2026: back to the original sticker
   language of 21 Oct, rebuilt for the page as it is now: three apps, just their names, a PIN badge, the burger).
   Grey #808080, lime #55FF00, black, and white only for small highlights. Everything that matters
   is a sticker: cut out with a 3px black outline and slapped down on a hard offset shadow; the big
   lettering is the logo's own lime with a fat black stroke round it.

   The palette, and what it forces:
     - the ground is mid-grey #808080; black text on it is 5.3:1, so black is the only colour text
       takes on the greys, and nothing behind text is ever darker than that grey (the dot screen,
       the swells and the ink only ever lighten it);
     - lime on grey is only 3:1, so lime is a fill (black on it, 15:1), or sits on black, or is
       lettering with the logo's black stroke round it: never plain lime text on grey;
     - white is only ever a small highlight or a sheen. No glass, no blur, no glows, no soft
       shadows, no gradients but the halftone and the little sheens.

   The logo is the picture itself (frizzy-g.jpg), whose background is exactly #808080: it's
   blended with hard-light, which leaves 50% grey neutral, so the picture's grey drops out and the
   dot screen and the ink run straight through it while the lettering stays as drawn.

   The burger in the corner, its panel and the PIN form in it are lookmenu.css's (the same stickers
   on every Frizzy G site): .top-end, .corner, .look-menu, .look-burger, .look-panel,
   .look-panel-label, .lm-opts, .lm-opt, .lm-night, .lm-frizzy, .lm-tom, .lm-castle, .lm-pin,
   .lm-pin-label, .lm-pin-row, .lm-pin-input, .lm-pin-go, .lm-pin-wrong. This sheet only keeps the
   logo out from under it.

   Hand-written, phone first at 390px, system fonts only; icons and emblems are data: SVGs. Loops
   move transform and opacity (and background-position on the go buttons' shine); everything stops
   under prefers-reduced-motion and the page still looks finished. The look's script (frizzy.js)
   only adds the ffx- classes at the end of this file: the page above them is complete without it.
   ========================================================================================= */

:root {
  color-scheme: light;

  /* the greys: the ground, and the steps up from it (all lighter, so black text only gains) */
  --grey: #808080;            /* the ground: black on it 5.3:1 */
  --dot: #8a8a8a;             /* the dot screen printed on the ground */
  --dot-2: #969696;           /* the halftone swells */
  --grey-2: #9b9b9b;          /* raised: the cards (black on it 7.6:1) */
  --grey-3: #b4b4b4;          /* lighter (black on it 10:1) */
  --lime: #55ff00;
  --ink: #000000;
  --paper: #ffffff;           /* small highlights only */

  /* the sticker language */
  --line: 3px;                /* every outline */
  --sh: 5px 5px 0 var(--ink); /* the hard shadow */
  --sh-s: 3px 3px 0 var(--ink);
  --sh-l: 7px 7px 0 var(--ink);
  --r-l: 22px;
  --r-m: 14px;
  --gutter: 16px;
  --focus: var(--ink);

  --font: "Segoe UI", system-ui, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Roboto, Arial, sans-serif;

  --ease: cubic-bezier(.2, .8, .2, 1);
  --spring: cubic-bezier(.34, 1.45, .64, 1);
  --slap: cubic-bezier(.25, 1.6, .45, 1);   /* a sticker slapped down: overshoots, then sits */

  /* the dot screen: a 45-degree lattice, 9.9px apart (two square grids, one offset half a tile);
     frizzy.js prints its live halftone on exactly this lattice */
  --screen: 14px 14px;

  /* the cartoon shine: two hard white bars, slid across a lime button with background-position */
  --glint: linear-gradient(105deg, rgba(255, 255, 255, 0) 45%, rgba(255, 255, 255, .77) 45% 47.2%, rgba(255, 255, 255, 0) 47.2% 48.6%, rgba(255, 255, 255, .77) 48.6% 49.3%, rgba(255, 255, 255, 0) 49.3%);
  /* the go arrow, in black (it sits on lime) */
  --i-go: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.6 8h9.6M8.4 3.6 12.8 8l-4.4 4.4' fill='none' stroke='%23000' stroke-width='2.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  /* the padlock on the PIN badge (a mask: it takes the badge's black) */
  --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.8'/%3E%3Crect x='.6' y='5' width='8.8' height='6.6' rx='1.6'/%3E%3C/svg%3E");
  /* the emblems: lime artwork on a black tile, with white highlights on the balls */
  --e-mbao: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 56 56'%3E%3Ccircle cx='19' cy='28' r='10.5' fill='%2355ff00'/%3E%3Ccircle cx='37.5' cy='28' r='10.5' fill='%2355ff00' stroke='%23000' stroke-width='2.5'/%3E%3Ccircle cx='15.6' cy='24.4' r='2.6' fill='%23fff'/%3E%3Ccircle cx='34.1' cy='24.4' r='2.6' fill='%23fff'/%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%3Cpath d='M13 35 C21 21 35 21 43 35' fill='none' stroke='%2355ff00' stroke-width='4' stroke-linecap='round'/%3E%3Ccircle cx='13' cy='35' r='8' fill='%2355ff00'/%3E%3Ccircle cx='43' cy='35' r='8' fill='%2355ff00'/%3E%3Ccircle cx='10.6' cy='32.4' r='2' fill='%23fff'/%3E%3Ccircle cx='40.6' cy='32.4' r='2' fill='%23fff'/%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%3Ccircle cx='19' cy='28' r='9.5' fill='%2355ff00'/%3E%3Ccircle cx='16' cy='24.8' r='2.4' fill='%23fff'/%3E%3Cg fill='none' stroke='%2355ff00' stroke-linecap='round'%3E%3Cpath d='M33 21.5a9.5 9.5 0 0 1 0 13' stroke-width='3.4'/%3E%3Cpath d='M38.5 17a16 16 0 0 1 0 22' stroke-width='3.2'/%3E%3Cpath d='M44 12.5a22.5 22.5 0 0 1 0 31' stroke-width='3'/%3E%3C/g%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);
    --slap: linear(0, .3 6%, .8 13%, 1.08 19%, 1.12 24%, 1.06 32%, .985 42%, .995 56%, 1);
  }
}

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

*, *::before, *::after { box-sizing: border-box; }
html {
  background: var(--grey);
  -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
}
body {
  margin: 0; min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; justify-content: center;
  color: var(--ink); font: 400 16px/1.5 var(--font);
  overflow-x: clip;
}
::selection { background: var(--lime); color: var(--ink); }
:focus-visible { outline: 3px 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 ground: grey, with a fine dot screen printed on it (lighter than the grey, never darker) */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background:
    radial-gradient(circle, var(--dot) 1.15px, rgba(138, 138, 138, 0) 1.75px) 0 0 / var(--screen),
    radial-gradient(circle, var(--dot) 1.15px, rgba(138, 138, 138, 0) 1.75px) 7px 7px / var(--screen),
    var(--grey);
}

/* the halftone swells (.ambient, three <i>): three big patches of the same dot screen with bigger
   dots, stepping down in size towards their edge. Each <i> is a whole-screen layer (so its dots
   sit exactly on the ground's screen) with three rings: big dots inside, then medium, then small.
   --x/--y is the centre, --s the radius (frizzy.js reads them, so its live version grows from
   exactly here). Lighter than the ground */
.ambient { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.ambient i, .ambient i::before, .ambient i::after {
  position: absolute; inset: 0; display: block;
  --swell: radial-gradient(circle, var(--dot-2) var(--d), rgba(150, 150, 150, 0) calc(var(--d) + .6px));
  background: var(--swell) 0 0 / var(--screen), var(--swell) 7px 7px / var(--screen);
}
.ambient i::before, .ambient i::after { content: ""; }
.ambient i { --d: 3.5px; -webkit-mask: radial-gradient(circle at var(--x) var(--y), #000 calc(var(--s) * .3), transparent calc(var(--s) * .5)); mask: radial-gradient(circle at var(--x) var(--y), #000 calc(var(--s) * .3), transparent calc(var(--s) * .5)); }
.ambient i::before { --d: 2.6px; -webkit-mask: radial-gradient(circle at var(--x) var(--y), #000 calc(var(--s) * .5), transparent calc(var(--s) * .75)); mask: radial-gradient(circle at var(--x) var(--y), #000 calc(var(--s) * .5), transparent calc(var(--s) * .75)); }
.ambient i::after { --d: 1.8px; -webkit-mask: radial-gradient(circle at var(--x) var(--y), #000 calc(var(--s) * .7), transparent var(--s)); mask: radial-gradient(circle at var(--x) var(--y), #000 calc(var(--s) * .7), transparent var(--s)); }
.ambient i:nth-child(1) { --x: 0vw; --y: 0vh; --s: 58vw; }    /* overhead, on the left */
.ambient i:nth-child(2) { --x: 104vw; --y: 46vh; --s: 50vw; }  /* coming in from the right */
.ambient i:nth-child(3) { --x: -6vw; --y: 96vh; --s: 56vw; }   /* low down */
.ambient i:nth-child(1), .ambient i:nth-child(1)::before, .ambient i:nth-child(1)::after { animation: ffx-breathe 9s ease-in-out infinite alternate; }
.ambient i:nth-child(2), .ambient i:nth-child(2)::before, .ambient i:nth-child(2)::after { animation: ffx-breathe 11s ease-in-out -4s infinite alternate; }
.ambient i:nth-child(3), .ambient i:nth-child(3)::before, .ambient i:nth-child(3)::after { animation: ffx-breathe 13s ease-in-out -7s infinite alternate; }

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

/* the logo and the cards sit together in the middle of the screen; on a phone the top leaves room
   for the burger, so the logo's G never sits under it */
.home {
  width: 100%; max-width: 560px; margin: 0 auto;
  display: flex; flex-direction: column; gap: 26px;
  padding: max(64px, calc(env(safe-area-inset-top) + 58px)) max(var(--gutter), env(safe-area-inset-right)) calc(44px + env(safe-area-inset-bottom)) max(var(--gutter), env(safe-area-inset-left));
}

/* ---------- the logo ---------- */

/* just the picture: its lettering fills the column; its grey margins hang off the sides, invisible
   (and clipped, so they can never push the page sideways) */
.logo { margin: 0; display: grid; justify-items: center; align-items: center; text-align: center; overflow-x: clip; }
.logo-img {
  grid-row: 1; grid-column: 1;
  display: block; width: 150%; max-width: none; height: auto; margin: -11% 0 -12%;
  mix-blend-mode: hard-light;
  pointer-events: none; -webkit-user-select: none; user-select: none;
  animation: ffx-stamp .7s var(--slap) .05s backwards;
}
.logo-text { display: none; }

/* ---------- the apps: grey stickers with lime ink printed in the corner ---------- */

.apps { display: flex; flex-direction: column; gap: 16px; padding: 0 5px 5px 0; }
.app {
  --card: var(--grey-2); --g: 1; --emblem: var(--e-mbao); --tilt: -4deg;
  position: relative; isolation: isolate;
  display: grid; grid-template-columns: 64px minmax(0, 1fr); grid-template-rows: auto auto;
  column-gap: 16px; row-gap: 0; align-items: center;
  min-height: 112px; padding: 16px 16px 16px 15px; border: var(--line) solid var(--ink); border-radius: var(--r-l);
  color: var(--ink); text-decoration: none; -webkit-tap-highlight-color: transparent;
  /* the halftone: three sizes of lime dot on one screen, each tier wiped out with the card's own
     grey beyond its reach, so the dots shrink as they leave the corner */
  background:
    radial-gradient(circle at 100% 0, rgba(155, 155, 155, 0) calc(var(--g) * 22%), var(--card) calc(var(--g) * 48%)),
    radial-gradient(circle, var(--lime) 0 1.2px, rgba(85, 255, 0, 0) 1.7px) 0 0 / 9px 9px,
    radial-gradient(circle at 100% 0, rgba(155, 155, 155, 0) calc(var(--g) * 11%), var(--card) calc(var(--g) * 31%)),
    radial-gradient(circle, var(--lime) 0 2.4px, rgba(85, 255, 0, 0) 2.9px) 0 0 / 9px 9px,
    radial-gradient(circle at 100% 0, rgba(155, 155, 155, 0) 0, var(--card) calc(var(--g) * 17%)),
    radial-gradient(circle, var(--lime) 0 3.6px, rgba(85, 255, 0, 0) 4.1px) 0 0 / 9px 9px,
    var(--card);
  box-shadow: var(--sh);
  transition: transform .45s var(--spring), box-shadow .2s var(--ease);
}
.app-mbao { --emblem: var(--e-mbao); --tilt: -4deg; --g: 1; }
.app-stretcher { --emblem: var(--e-stretcher); --tilt: 3deg; --g: .85; }
.app-earshot { --emblem: var(--e-earshot); --tilt: -2deg; --g: 1.15; }
/* the emblem: a black tile with the app's mark in lime, stuck on a little crooked */
.app::before {
  content: ""; grid-column: 1; grid-row: 1 / span 2; width: 64px; height: 64px; border-radius: 18px;
  background: var(--emblem) center / 64px 64px no-repeat, var(--ink);
  box-shadow: 3px 3px 0 var(--grey);
  transform: rotate(var(--tilt));
  transition: transform .5s var(--spring);
}
/* the name: the logo's lettering (see below), and all a card says now (George: "only app titles"),
   so it's big. Its size follows the column, so the longest ("Stretcher") stays on one line on a
   phone and all three stay the same size. It runs the width of the card and carries the go
   button at its right-hand end */
.app-name {
  --o: .085em; --dx: .06em; --dy: .065em;
  grid-column: 2; grid-row: 1 / span 2; align-self: center; justify-self: stretch; position: relative;
  padding: 0 62px .04em .02em;
  font: italic 900 clamp(26px, 10vw - 6px, 36px)/1.12 var(--font); letter-spacing: .005em;
}
/* the go button: a lime sticker with a black arrow at the end of the name (decoration: the whole
   card is the link). It catches the light every few seconds, the cartoon shine running down the
   cards in turn */
.app-name::after {
  content: ""; position: absolute; right: 0; top: 50%; width: 46px; height: 46px; margin-top: -23px; border-radius: 50%;
  background: var(--i-go) center / 20px 20px no-repeat, var(--glint) 160% 0 / 250% 100% no-repeat, var(--lime);
  border: var(--line) solid var(--ink); box-shadow: var(--sh-s);
  transition: transform .45s var(--spring), box-shadow .2s var(--ease);
  animation: ffx-shine 6s ease-in-out 1.6s infinite;
}
.app-stretcher .app-name::after { animation-delay: 1.85s; }
.app-earshot .app-name::after { animation-delay: 2.1s; }

/* PIN: the friends-only apps (George's PIN, see pin\README.md). A little lime sticker slapped across
   the bottom of the emblem, crooked, with a padlock and the word in heavy black italic. It's real
   text, so a screen reader says it with the app's name */
.app-lock {
  --lock-at: translateY(28px); --lock-r: -6deg;
  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: 21px; padding: 0 7px 0 6px; border-radius: 999px;
  font: italic 900 10.5px/1 var(--font); letter-spacing: .08em; color: var(--ink); white-space: nowrap;
  background: var(--lime); border: 2.5px solid var(--ink); box-shadow: 2px 2px 0 var(--ink);
  transform: var(--lock-at) rotate(var(--lock-r));
  transition: transform .5s var(--spring);
  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 sticker are centred together */
.app-locked::before { margin-bottom: 10px; }

@media (hover: hover) {
  .app:hover { transform: translate(-2px, -2px); box-shadow: var(--sh-l); }
  .app:hover::before { transform: rotate(calc(var(--tilt) * -1)) scale(1.06); }
  .app:hover .app-lock { --lock-r: 4deg; }
  .app:hover .app-name::after { transform: translateX(3px); }
}
/* pressed: the sticker goes down into its shadow */
.app:active { transform: translate(3px, 3px); box-shadow: 2px 2px 0 var(--ink); transition-duration: .08s, .08s; }
.app:focus-visible { outline: 3px solid var(--focus); outline-offset: 5px; }

/* the logo's lettering: lime letters in a fat black outline with a hard black shadow under it. The
   letters are fattened a hair with a stroke of their own colour (closing the notches heavy
   italics cut into their joins), the outline is twelve copies set round a circle under the text
   and the shadow eight more moved down and right. All text-shadows, never a filter. --o is the
   outline, --dx --dy the shadow (in em) */
.app-name, .ffx-decode { --fill: var(--lime); --edge: var(--ink); --drop: var(--ink); --dil: .02em; }
.app-name, .ffx-decode, .ffx-decode .ffx-q {
  color: var(--fill);
  -webkit-text-stroke: var(--dil) var(--fill);
  text-shadow:
    var(--o) 0 0 var(--edge),
    calc(var(--o) * .866) calc(var(--o) * .5) 0 var(--edge),
    calc(var(--o) * .5) calc(var(--o) * .866) 0 var(--edge),
    0 var(--o) 0 var(--edge),
    calc(var(--o) * -.5) calc(var(--o) * .866) 0 var(--edge),
    calc(var(--o) * -.866) calc(var(--o) * .5) 0 var(--edge),
    calc(var(--o) * -1) 0 0 var(--edge),
    calc(var(--o) * -.866) calc(var(--o) * -.5) 0 var(--edge),
    calc(var(--o) * -.5) calc(var(--o) * -.866) 0 var(--edge),
    0 calc(var(--o) * -1) 0 var(--edge),
    calc(var(--o) * .5) calc(var(--o) * -.866) 0 var(--edge),
    calc(var(--o) * .866) calc(var(--o) * -.5) 0 var(--edge),
    calc(var(--dx) + var(--o) * .766) calc(var(--dy) + var(--o) * -.643) 0 var(--drop),
    calc(var(--dx) + var(--o) * .963) calc(var(--dy) + var(--o) * -.271) 0 var(--drop),
    calc(var(--dx) + var(--o) * .989) calc(var(--dy) + var(--o) * .149) 0 var(--drop),
    calc(var(--dx) + var(--o) * .84) calc(var(--dy) + var(--o) * .543) 0 var(--drop),
    calc(var(--dx) + var(--o) * .543) calc(var(--dy) + var(--o) * .84) 0 var(--drop),
    calc(var(--dx) + var(--o) * .149) calc(var(--dy) + var(--o) * .989) 0 var(--drop),
    calc(var(--dx) + var(--o) * -.271) calc(var(--dy) + var(--o) * .963) 0 var(--drop),
    calc(var(--dx) + var(--o) * -.643) calc(var(--dy) + var(--o) * .766) 0 var(--drop);
}

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

/* one-shot entrances: the logo is stamped down, the stickers slapped on one after another, then
   the PIN stickers on top of them. Transform only, filling backwards: content is readable from the
   first frame */
.app { animation: ffx-slap .6s var(--slap) .12s backwards; }
.app-stretcher { animation-delay: .18s; }
.app-earshot { animation-delay: .24s; }
.app-lock { animation: ffx-lock .5s var(--slap) .55s backwards; }

@keyframes ffx-stamp { from { transform: scale(1.12) rotate(-2deg); } }
@keyframes ffx-slap { from { transform: translate(-6px, -8px) rotate(-1.4deg) scale(1.03); } }
@keyframes ffx-lock { from { transform: var(--lock-at) rotate(-12deg) scale(1.3); } } /* (small enough never to reach the words) */
@keyframes ffx-breathe { from { opacity: .72; } to { opacity: 1; } }
@keyframes ffx-shine { 0% { background-position: center, 160% 0, 0 0; } 22%, 100% { background-position: center, -60% 0, 0 0; } }

/* 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 { transform: none; box-shadow: var(--sh-s); }
}

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

@media (max-width: 374px) {
  :root { --gutter: 12px; }
  .home { gap: 22px; }
  .app { grid-template-columns: 56px minmax(0, 1fr); column-gap: 13px; min-height: 100px; padding: 14px 13px 14px 12px; }
  .app::before { width: 56px; height: 56px; border-radius: 16px; background-size: 56px 56px, auto; }
  .app-name { padding-right: 54px; }
  .app-name::after { width: 41px; height: 41px; margin-top: -20.5px; background-size: 18px 18px, 250% 100%, auto; }
  .app-lock { --lock-at: translateY(24px); height: 20px; padding: 0 6px 0 5px; font-size: 10px; }
}

/* a desktop: the logo goes big across the top and the three stickers stand side by side under it,
   the emblem up top, the name and its go button along the bottom */
@media (min-width: 900px) {
  :root { --gutter: 32px; }
  .home { max-width: 1160px; gap: 40px; padding-top: 44px; padding-bottom: 56px; }
  .logo-img { width: min(150%, 1060px); margin: -88px 0 -84px; }
  .apps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 26px 28px; padding: 0 7px 7px 0; }
  .app {
    grid-template-columns: minmax(0, 1fr); grid-template-rows: 1fr auto; row-gap: 0;
    align-items: start; min-height: 228px; padding: 26px 24px 26px; border-radius: 26px; box-shadow: var(--sh-l);
    --g: 1.1;
  }
  .app-stretcher { --g: .95; }
  .app-earshot { --g: 1.25; }
  .app::before { grid-column: 1; grid-row: 1; width: 88px; height: 88px; border-radius: 24px; margin-bottom: 24px; background-size: 88px 88px, auto; box-shadow: 4px 4px 0 var(--grey); }
  .app-name { grid-column: 1; grid-row: 2; align-self: end; font-size: clamp(24px, 3.2vw - 5px, 38px); padding-right: 64px; }
  .app-name::after { width: 52px; height: 52px; margin-top: -26px; background-size: 22px 22px, 250% 100%, auto; }
  /* the PIN sticker across the bottom of the emblem, centred under it */
  .app-lock { --lock-at: translate(calc(44px - 50%), 76px); grid-row: 1; align-self: start; justify-self: start; height: 23px; padding: 0 8px 0 7px; font-size: 11.5px; }
  @media (hover: hover) { .app:hover { box-shadow: 9px 9px 0 var(--ink); } }
  .app:active { box-shadow: 4px 4px 0 var(--ink); }
}

/* big screens: the swells spread into the margins */
@media (min-width: 1100px) {
  .ambient i:nth-child(1) { --x: 12vw; --y: 4vh; --s: 30vw; }
  .ambient i:nth-child(2) { --x: 94vw; --y: 44vh; --s: 27vw; }
  .ambient i:nth-child(3) { --x: 14vw; --y: 100vh; --s: 30vw; }
}

/* more contrast asked for: solid edges, no texture */
@media (prefers-contrast: more) {
  :root { --dot: #808080; --dot-2: #808080; }
  .ambient { display: none; }
  .app { background: var(--grey-2); }
}

/* Windows high contrast: keep every edge and state visible; the picture blends normally */
@media (forced-colors: active) {
  .app, .app-lock { border: 2px solid CanvasText; }
  .app-lock::before { background: CanvasText; }
  .ambient, body::before, .app::before { display: none; }
  .logo-img { mix-blend-mode: normal; }
  .app-name { -webkit-text-stroke: 0; text-shadow: none; color: CanvasText; }
}

/* =========================================================================================
   Effects. The look's script (frizzy.js) adds the ffx- classes below while it runs: only on
   Frizzy G, 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-frizzy: on; } /* tells the script this sheet is live (the switch flips sheets late) */

/* the live ground: a WebGL halftone drawn into the .ambient layer. It fades in over the CSS
   dots, which then rest, and come straight back if the GPU drops it */
.ffx-sky { position: absolute; inset: 0; display: block; width: 100%; height: 100%; opacity: 0; transition: opacity .7s var(--ease); }
.ffx-sky.ffx-in { opacity: 1; }
.ambient.ffx-gl i { visibility: hidden; animation-play-state: paused; }
.ambient.ffx-gl i::before, .ambient.ffx-gl i::after { animation-play-state: paused; }

/* confetti, stars, balls and sparks: one canvas over the page (under the burger), only while
   something flies */
.ffx-burst { position: fixed; inset: 0; z-index: 30; display: block; width: 100%; height: 100%; pointer-events: none; }

/* 3D stickers: 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, under the
   words (z-index -1 inside the card): a faint light plus the cartoon shine, two hard white bars */
.ffx-tilt { will-change: transform; transition: box-shadow .2s var(--ease); }
.ffx-glare { position: absolute; inset: 0; z-index: -1; border-radius: calc(var(--r-l) - 3px); overflow: hidden; pointer-events: none; opacity: 0; }
.ffx-glare i {
  position: absolute; display: block; left: -50%; top: -50%; width: 200%; height: 200%;
  background:
    linear-gradient(115deg, rgba(255, 255, 255, 0) 44%, rgba(255, 255, 255, .55) 44% 48.5%, rgba(255, 255, 255, 0) 48.5% 50.5%, rgba(255, 255, 255, .55) 50.5% 51.8%, rgba(255, 255, 255, 0) 51.8%),
    radial-gradient(closest-side, rgba(255, 255, 255, .3), rgba(255, 255, 255, .1) 45%, rgba(255, 255, 255, 0) 70%);
}
@media (min-width: 900px) { .ffx-glare { border-radius: 23px; } }

/* 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. The scrambled letters
   are printed inside out: black, edged in lime */
.ffx-decoding { position: relative; color: transparent; -webkit-text-stroke-color: transparent; text-shadow: none; }
.ffx-decode {
  position: absolute; left: 0; top: 0; right: 0; padding: inherit; white-space: nowrap;
  pointer-events: none; -webkit-user-select: none; user-select: none;
}
.ffx-decode .ffx-q { --fill: var(--ink); --edge: var(--lime); --drop: var(--ink); }
.ffx-decode .ffx-hit { animation: ffx-hit .45s var(--ease); }
@keyframes ffx-hit { from { color: var(--paper); -webkit-text-stroke-color: var(--paper); } }

/* a ripple from the finger: a hard-edged white disc, as if the sticker flexed (under the words) */
.ffx-ripple { position: absolute; inset: 0; z-index: -1; border-radius: calc(var(--r-l) - 3px); overflow: hidden; pointer-events: none; }
@media (min-width: 900px) { .ffx-ripple { border-radius: 23px; } }
.ffx-ripple i { position: absolute; display: block; border-radius: 50%; background: rgba(255, 255, 255, .44); }

@media (forced-colors: active) {
  .ffx-sky, .ffx-burst, .ffx-glare, .ffx-ripple, .ffx-decode { display: none; }
  .ffx-decoding { color: CanvasText; }
}
