/* ==========================================================================
   PDF tools — the glass design system

   Every page under /pdf/ is built from this file alone: no main.css, none
   of the portfolio's header, footer, serif display face or chapter hues.
   The surface is the one the compressor v2 introduced — smoked glass over
   a slow violet glow, rims that catch light along the top, a soft bloom
   underneath — promoted from a tool's panel to the whole page.

   Shared pieces are `g-` classes. A tool's own pieces live in its page's
   <style> under its own prefix (pc- protect, pu- unlock, …).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
  --bg: #08070d;
  --bg-deep: #050409;

  /* Ink on glass */
  --g-ink: #f4f2fb;
  --g-ink-2: rgb(214 209 232 / .74);
  --g-ink-3: rgb(200 195 220 / .52);
  --g-ink-4: rgb(200 195 220 / .34);

  /* Violet */
  --g-lilac: #b3a6ff;
  --g-violet: #8f80f5;
  --g-violet-deep: #6f5fe4;
  --hue: #a99bff;
  --hue-soft: rgb(169 155 255 / .14);
  --hue-line: rgb(169 155 255 / .4);

  /* Rims */
  --g-rim: rgb(255 255 255 / .15);
  --g-rim-soft: rgb(255 255 255 / .08);
  --g-rim-faint: rgb(255 255 255 / .05);

  /* Semantic */
  --pos: #7ee2a8;
  --neg: #f29a8e;
  --warn: #f6c177;

  /* Category tints, used by tool icons and nothing else. */
  --cat-organize: #b9adff;
  --cat-optimize: #7ee2a8;
  --cat-convert: #f6c177;
  --cat-edit: #f5a3c7;
  --cat-security: #8fc1ff;
  --cat-print: #7fd8e8;

  --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;

  --gutter: clamp(1rem, 4vw, 2rem);
  --wide: 76rem;

  --ease: cubic-bezier(.22, .61, .36, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --spring: cubic-bezier(.34, 1.56, .64, 1);
  --dur-1: 160ms;
  --dur-2: 320ms;
  --dur-3: 620ms;

  color-scheme: dark;
}

/* --------------------------------------------------------------------------
   2. Reset and base
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; overflow-x: clip; scroll-padding-top: 1rem; }
body {
  min-height: 100svh;
  background: var(--bg);
  color: var(--g-ink);
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
  overflow-wrap: break-word;
  display: flex;
  flex-direction: column;
}
body > main { flex: 1 0 auto; }
img, svg, video, canvas { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; }
:where(h1, h2, h3, h4) { font-weight: 650; line-height: 1.15; letter-spacing: -.015em; text-wrap: balance; }
p { text-wrap: pretty; }
a { color: inherit; text-decoration-color: rgb(179 166 255 / .45); text-underline-offset: .22em; }
a:hover { text-decoration-color: currentColor; }
::selection { background: rgb(169 155 255 / .45); color: #fff; }
:focus-visible { outline: 2px solid var(--g-lilac); outline-offset: 3px; border-radius: 6px; }
fieldset { border: 0; padding: 0; min-width: 0; }
legend { padding: 0; }
[hidden] { display: none !important; }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.g-skip {
  position: absolute; left: 1rem; top: -100px; z-index: 300;
  padding: .7rem 1.1rem; border-radius: 10px; font-weight: 650; text-decoration: none;
  background: var(--g-lilac); color: #120f1f;
  transition: top var(--dur-2) var(--ease-out);
}
.g-skip:focus { top: 1rem; }

/* --------------------------------------------------------------------------
   3. Ambient light — behind every page

   Five pools of colour, each wandering on its own long loop. The durations
   share no common factor, so the pattern never visibly repeats. Whole
   layers move (transform), nothing repaints. Fixed to the viewport, so
   glass anywhere on the page has something to blur.
   -------------------------------------------------------------------------- */

.g-aura { position: fixed; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }
.g-aura::before {
  /* A floor of light so the top of the page is never flat black. */
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(70rem 40rem at 50% -12rem, rgb(124 92 255 / .2), transparent 70%),
    radial-gradient(40rem 30rem at 100% 100%, rgb(96 64 210 / .12), transparent 70%);
}
.g-aura i {
  position: absolute; border-radius: 50%; will-change: transform;
  background: radial-gradient(closest-side, var(--c), transparent);
  animation: var(--drift) var(--t) ease-in-out infinite alternate;
}
.g-aura i:nth-child(1) { left: 28%; top: -10%; width: 46vw; height: 46vw; --c: rgb(124 92 255 / .34); --drift: g-drift-1; --t: 43s; }
.g-aura i:nth-child(2) { left: -12%; top: 18%; width: 40vw; height: 52vw; --c: rgb(92 98 240 / .2); --drift: g-drift-2; --t: 57s; }
.g-aura i:nth-child(3) { left: 68%; top: 12%; width: 38vw; height: 52vw; --c: rgb(158 82 232 / .2); --drift: g-drift-3; --t: 61s; }
.g-aura i:nth-child(4) { left: 20%; top: 58%; width: 60vw; height: 40vw; --c: rgb(96 64 210 / .16); --drift: g-drift-4; --t: 71s; }
.g-aura i:nth-child(5) { left: 74%; top: 70%; width: 32vw; height: 32vw; --c: rgb(76 120 255 / .12); --drift: g-drift-2; --t: 83s; animation-direction: alternate-reverse; }
@keyframes g-drift-1 {
  0% { transform: translate(0, 0) scale(1); }
  30% { transform: translate(14%, 8%) scale(1.08); }
  55% { transform: translate(-6%, 14%) scale(.94); }
  80% { transform: translate(-16%, -2%) scale(1.06); }
  100% { transform: translate(6%, -6%) scale(1); }
}
@keyframes g-drift-2 {
  0% { transform: translate(0, 0) scale(1); }
  35% { transform: translate(22%, -10%) scale(1.12); }
  70% { transform: translate(8%, 16%) scale(.92); }
  100% { transform: translate(30%, 4%) scale(1.04); }
}
@keyframes g-drift-3 {
  0% { transform: translate(0, 0) scale(1.04); }
  40% { transform: translate(-24%, 12%) scale(.94); }
  75% { transform: translate(-10%, -14%) scale(1.1); }
  100% { transform: translate(-30%, 2%) scale(1); }
}
@keyframes g-drift-4 {
  0% { transform: translate(0, 0) scale(1); }
  45% { transform: translate(-12%, -16%) scale(1.1); }
  100% { transform: translate(14%, -8%) scale(.96); }
}
/* A whisper of grain, so the gradients never band on cheap panels. */
.g-aura::after {
  content: ""; position: absolute; inset: 0; opacity: .045; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* --------------------------------------------------------------------------
   4. Layout
   -------------------------------------------------------------------------- */

.g-wrap { width: 100%; max-width: var(--wide); margin-inline: auto; padding-inline: var(--gutter); }
.g-wrap--tool { max-width: 62rem; }
.g-section { padding-block: clamp(2rem, 5vw, 3.5rem); }
.g-stack > * + * { margin-top: 1rem; }

/* --------------------------------------------------------------------------
   5. Glass recipes
   -------------------------------------------------------------------------- */

/* The panel: a faint light-to-dark sheen, a rim that catches light at the
   top, and a soft violet bloom underneath. */
.g-card {
  position: relative;
  border-radius: 24px;
  background: linear-gradient(180deg, rgb(255 255 255 / .065), rgb(255 255 255 / .025));
  border: 1px solid var(--g-rim-soft);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / .1),
    0 24px 50px -28px rgb(0 0 0 / .85),
    0 0 40px -24px rgb(130 105 255 / .35);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  backdrop-filter: blur(18px) saturate(140%);
}
.g-card--pad { padding: clamp(1.1rem, 3vw, 1.6rem); }

/* The thick bezel: a bright rim around a darker inset well. Used for the
   drop panel and anything that is the page's main event. */
.g-bezel {
  position: relative; padding: 9px; border-radius: 40px;
  background: linear-gradient(180deg, rgb(255 255 255 / .13), rgb(255 255 255 / .04) 40%, rgb(255 255 255 / .07));
  border: 1px solid rgb(255 255 255 / .16);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / .3),
    inset 0 -1px 0 rgb(180 165 255 / .28),
    0 40px 80px -30px rgb(0 0 0 / .9),
    0 0 80px -24px rgb(130 105 255 / .5);
  -webkit-backdrop-filter: blur(24px) saturate(150%);
  backdrop-filter: blur(24px) saturate(150%);
}
.g-bezel::before, .g-bezel::after { content: ""; position: absolute; pointer-events: none; border-radius: 2px; }
.g-bezel::before {
  top: -1px; left: 16%; right: 16%; height: 2px;
  background: linear-gradient(90deg, transparent, rgb(228 222 255 / .95) 50%, transparent);
  box-shadow: 0 0 16px 2px rgb(170 150 255 / .55);
}
.g-bezel::after {
  bottom: -1px; left: 24%; right: 24%; height: 1px;
  background: linear-gradient(90deg, transparent, rgb(160 140 255 / .75) 50%, transparent);
  box-shadow: 0 0 20px 3px rgb(120 95 255 / .35);
}

/* A recessed well: inputs, tracks and wells sit into the glass. */
.g-well {
  background: rgb(10 8 18 / .55);
  border: 1px solid rgb(255 255 255 / .08);
  box-shadow: inset 0 1px 3px rgb(0 0 0 / .55), 0 1px 0 rgb(255 255 255 / .04);
}

/* --------------------------------------------------------------------------
   6. Header
   -------------------------------------------------------------------------- */

.g-top { position: relative; z-index: 50; padding: .9rem 0 0; }
.g-top__bar {
  display: flex; align-items: center; gap: .75rem;
  min-height: 3.5rem; padding: .45rem .5rem .45rem .9rem; border-radius: 20px;
  background: linear-gradient(180deg, rgb(255 255 255 / .075), rgb(255 255 255 / .03));
  border: 1px solid var(--g-rim-soft);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .1), 0 18px 40px -26px rgb(0 0 0 / .9);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  backdrop-filter: blur(20px) saturate(150%);
}
.g-brand { display: inline-flex; align-items: center; gap: .6rem; text-decoration: none; color: var(--g-ink); flex: none; }
.g-brand__mark { width: 30px; height: 30px; flex: none; filter: drop-shadow(0 4px 10px rgb(130 105 255 / .45)); }
.g-brand__text { font-weight: 650; font-size: 1.02rem; letter-spacing: -.01em; white-space: nowrap; }
.g-brand__text span { color: var(--g-ink-3); font-weight: 500; }

.g-nav { display: flex; align-items: center; gap: .15rem; margin-left: .75rem; }
.g-nav a, .g-nav button {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .5rem .75rem; border-radius: 12px; border: 0; background: none;
  font-size: .9rem; font-weight: 550; color: var(--g-ink-2); text-decoration: none; white-space: nowrap;
  transition: color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}
.g-nav a:hover, .g-nav button:hover, .g-nav [aria-expanded="true"], .g-nav [aria-current="page"] { color: var(--g-ink); background: rgb(255 255 255 / .06); }
.g-nav svg { width: 14px; height: 14px; transition: transform var(--dur-2) var(--ease-out); }
.g-nav [aria-expanded="true"] svg { transform: rotate(180deg); }
.g-top__end { margin-left: auto; display: flex; align-items: center; gap: .5rem; }

/* "Nothing leaves your device", as a pill: the promise every page makes. */
.g-private {
  display: inline-flex; align-items: center; gap: .45rem; white-space: nowrap;
  padding: .32rem .7rem; border-radius: 999px;
  font-size: .76rem; font-weight: 600; color: var(--pos);
  background: rgb(126 226 168 / .08); border: 1px solid rgb(126 226 168 / .28);
}
.g-private svg { width: 13px; height: 13px; flex: none; }
.g-home {
  display: inline-flex; align-items: center; gap: .4rem; padding: .5rem .8rem; border-radius: 12px;
  font-size: .86rem; font-weight: 550; color: var(--g-ink-3); text-decoration: none; white-space: nowrap;
}
.g-home:hover { color: var(--g-ink); background: rgb(255 255 255 / .06); }
.g-home svg { width: 13px; height: 13px; }
/* The PDF tools are the only part of james-johnson.dev that's live for now, so
   links to the rest are hidden. Delete this rule to bring them back. */
[data-main-site] { display: none !important; }

/* The all-tools menu: a glass sheet under the bar, a column per category. */
.g-menu {
  position: absolute; left: 0; right: 0; top: calc(100% + .5rem);
  padding: 1.25rem; border-radius: 24px;
  background: linear-gradient(180deg, rgb(34 30 50 / .94), rgb(18 16 28 / .96));
  border: 1px solid rgb(255 255 255 / .12);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .12), 0 40px 90px -30px rgb(0 0 0 / .95), 0 0 60px -24px rgb(130 105 255 / .5);
  -webkit-backdrop-filter: blur(24px) saturate(150%);
  backdrop-filter: blur(24px) saturate(150%);
  opacity: 0; transform: translateY(-6px) scale(.99); transform-origin: 50% 0; pointer-events: none;
  transition: opacity var(--dur-2) var(--ease), transform var(--dur-2) var(--ease-out);
}
.g-menu.is-open { opacity: 1; transform: none; pointer-events: auto; }
.g-menu__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: 1rem 1.5rem; }
.g-menu__cat { font-size: .72rem; font-weight: 650; letter-spacing: .08em; text-transform: uppercase; color: var(--g-ink-3); margin: 0 0 .4rem .55rem; }
.g-menu__list { list-style: none; padding: 0; display: grid; gap: 1px; }
.g-menu__list a {
  display: flex; align-items: center; gap: .6rem; padding: .42rem .55rem; border-radius: 10px;
  font-size: .9rem; color: var(--g-ink-2); text-decoration: none;
}
.g-menu__list a:hover, .g-menu__list a:focus-visible { color: var(--g-ink); background: rgb(255 255 255 / .06); }
.g-menu__list a[aria-disabled="true"] { opacity: .5; pointer-events: none; }
.g-menu__list .g-icon { --size: 26px; --r: 8px; }
.g-menu__all { display: inline-flex; margin-top: 1rem; padding-left: .55rem; font-size: .88rem; color: var(--g-lilac); }

.g-burger { display: none; }

@media (max-width: 980px) {
  .g-nav a:not([data-keep]) { display: none; }
  .g-home span { display: none; }
}
@media (max-width: 620px) {
  .g-top__bar { padding-left: .7rem; gap: .4rem; }
  .g-nav { margin-left: auto; }
  .g-top__end { margin-left: 0; }
  .g-private span, .g-home { display: none; }
  .g-private { padding: .4rem; }
  .g-menu { padding: 1rem; max-height: calc(100dvh - 6rem); overflow: auto; }
}

/* --------------------------------------------------------------------------
   7. Tool icons — a tinted glass tile with a line glyph
   -------------------------------------------------------------------------- */

.g-icon {
  --size: 48px; --r: 14px; --c: var(--g-lilac);
  position: relative; display: grid; place-items: center; flex: none;
  width: var(--size); height: var(--size); border-radius: var(--r);
  color: var(--c);
  background:
    radial-gradient(120% 90% at 30% 0%, color-mix(in srgb, var(--c) 30%, transparent), transparent 70%),
    linear-gradient(180deg, color-mix(in srgb, var(--c) 16%, rgb(255 255 255 / .04)), rgb(255 255 255 / .02));
  border: 1px solid color-mix(in srgb, var(--c) 34%, transparent);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .18), 0 10px 22px -14px color-mix(in srgb, var(--c) 80%, transparent);
}
.g-icon svg { width: 56%; height: 56%; overflow: visible; }
.g-icon svg * { vector-effect: non-scaling-stroke; }
[data-cat="organize"] { --c: var(--cat-organize); }
[data-cat="optimize"] { --c: var(--cat-optimize); }
[data-cat="convert"] { --c: var(--cat-convert); }
[data-cat="edit"] { --c: var(--cat-edit); }
[data-cat="security"] { --c: var(--cat-security); }
[data-cat="print"] { --c: var(--cat-print); }

/* --------------------------------------------------------------------------
   8. Tool page hero
   -------------------------------------------------------------------------- */

.g-hero { padding: clamp(2rem, 6vw, 3.75rem) 0 clamp(1.25rem, 3vw, 2rem); text-align: center; }
.g-hero .g-icon { --size: 64px; --r: 19px; margin: 0 auto 1.1rem; }
.g-hero h1 {
  font-size: clamp(2rem, 5vw, 3.1rem); font-weight: 680; letter-spacing: -.025em;
  background: linear-gradient(180deg, #fff 30%, #cfc6ff);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.g-hero p { max-width: 38rem; margin: .7rem auto 0; font-size: clamp(1rem, 1.6vw, 1.12rem); color: var(--g-ink-2); }
.g-crumbs { display: flex; justify-content: center; gap: .5rem; margin-bottom: 1rem; font-size: .82rem; color: var(--g-ink-3); }
.g-crumbs a { color: var(--g-ink-3); text-decoration: none; }
.g-crumbs a:hover { color: var(--g-ink); }
.g-crumbs li { list-style: none; display: flex; gap: .5rem; }
.g-crumbs li + li::before { content: "/"; color: var(--g-ink-4); }
.g-crumbs ol { display: contents; }

/* --------------------------------------------------------------------------
   9. The drop panel
   -------------------------------------------------------------------------- */

.g-drop {
  position: relative; display: grid; justify-items: center; align-content: center;
  min-height: clamp(17rem, 30vw, 22rem); padding: 2.25rem 1.5rem 1.9rem;
  border-radius: 31px; text-align: center; cursor: pointer; overflow: hidden;
  background:
    radial-gradient(80% 55% at 50% 0%, rgb(255 255 255 / .07), transparent 70%),
    linear-gradient(180deg, #1e1c27 0%, #15131c 100%);
  border: 1px solid rgb(255 255 255 / .07);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / .06),
    inset 0 24px 40px -24px rgb(0 0 0 / .65),
    inset 0 -16px 40px -20px rgb(120 100 255 / .1);
  transition: background var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease), min-height var(--dur-3) var(--ease-out), padding var(--dur-3) var(--ease-out);
  -webkit-user-select: none; user-select: none;
}
.g-drop:hover, .g-drop:focus-visible, .g-drop.is-over {
  outline: none;
  border-color: rgb(179 166 255 / .35);
  background:
    radial-gradient(80% 60% at 50% 0%, rgb(169 155 255 / .14), transparent 70%),
    linear-gradient(180deg, #211e2d 0%, #17151f 100%);
}
.g-drop:focus-visible { box-shadow: 0 0 0 2px var(--g-lilac), inset 0 1px 0 rgb(255 255 255 / .06); }

/* Corner brackets; they step outwards while a file is held over the
   panel, and breathe out of step with each other the rest of the time. */
.g-corner {
  position: absolute; width: 34px; height: 34px; color: rgb(185 172 255 / .55);
  transition: transform var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease);
  animation: g-breathe 9s ease-in-out infinite;
}
.g-corner--tl { top: 28px; left: 28px; }
.g-corner--tr { top: 28px; right: 28px; animation-delay: -2.3s; }
.g-corner--bl { bottom: 28px; left: 28px; animation-delay: -6.8s; }
.g-corner--br { bottom: 28px; right: 28px; animation-delay: -4.9s; }
.g-drop:hover .g-corner, .g-drop.is-over .g-corner { color: rgb(200 190 255 / .85); }
.g-drop.is-over .g-corner--tl { transform: translate(-8px, -8px); }
.g-drop.is-over .g-corner--tr { transform: translate(8px, -8px); }
.g-drop.is-over .g-corner--bl { transform: translate(-8px, 8px); }
.g-drop.is-over .g-corner--br { transform: translate(8px, 8px); }
@keyframes g-breathe { 0%, 100% { opacity: .7; } 50% { opacity: 1; } }

.g-drop__full { display: grid; justify-items: center; }
.g-drop__art { display: block; width: clamp(150px, 19vw, 200px); aspect-ratio: 220 / 180; }
.g-drop__art > svg { width: 100%; height: 100%; overflow: visible; transition: transform var(--dur-3) var(--ease-out); }
.g-drop:hover .g-drop__art > svg, .g-drop.is-over .g-drop__art > svg { transform: translateY(-4px); }
.g-drop__title { margin-top: 1rem; font-size: clamp(1.5rem, 3.4vw, 2.2rem); font-weight: 650; letter-spacing: -.015em; line-height: 1.15; }
.g-drop__sub { margin-top: .45rem; font-size: clamp(1rem, 1.8vw, 1.25rem); color: var(--g-ink-2); }
.g-browse { color: var(--g-lilac); text-decoration: underline; text-decoration-thickness: 1.5px; text-decoration-color: rgb(179 166 255 / .6); text-underline-offset: .3em; }
.g-drop__foot { margin-top: clamp(1.25rem, 3.5vw, 2.1rem); font-size: .86rem; color: var(--g-ink-3); }

/* Collapsed: with files in, the panel becomes a slim bar so the work
   moves up. */
.g-drop__compact { display: none; align-items: center; justify-content: center; gap: .85rem; text-align: left; }
.g-drop.is-collapsed { min-height: 0; padding: .95rem 1.4rem; }
.g-drop.is-collapsed .g-drop__full, .g-drop.is-collapsed .g-corner { display: none; }
.g-drop.is-collapsed .g-drop__compact { display: flex; }
.g-drop__mini { width: 38px; height: 38px; flex: none; overflow: visible; filter: drop-shadow(0 4px 10px rgb(120 100 255 / .35)); }
.g-drop__compact b { display: block; font-size: 1rem; font-weight: 620; color: var(--g-ink); }
.g-drop__compact small { display: block; font-size: .9rem; color: var(--g-ink-2); }

/* The floating document art: each layer drifts on its own loop. */
.g-fl { transform-box: fill-box; transform-origin: 50% 50%; animation: var(--fl) var(--t) ease-in-out infinite; }
.g-fl--front { --fl: g-front; --t: 7.3s; }
.g-fl--back { --fl: g-back; --t: 13.1s; animation-direction: alternate; }
.g-fl--badge { --fl: g-badge; --t: 6.7s; animation-delay: -1.4s; }
.g-fl--glow { --fl: g-glow; --t: 8.9s; animation-direction: alternate; }
@keyframes g-front {
  0%, 100% { transform: translateY(0) rotate(0); }
  30% { transform: translateY(-6px) rotate(.6deg); }
  55% { transform: translateY(-2.5px) rotate(-.3deg); }
  80% { transform: translateY(-7px) rotate(.4deg); }
}
@keyframes g-back {
  0% { transform: translate(0, 0) rotate(0); }
  50% { transform: translate(-3px, 2px) rotate(-1.4deg); }
  100% { transform: translate(1px, 4px) rotate(1deg); }
}
@keyframes g-badge {
  0%, 100% { transform: translate(0, 0) rotate(0); }
  35% { transform: translate(3px, -6px) rotate(3deg); }
  70% { transform: translate(1px, -3px) rotate(-2deg); }
}
@keyframes g-glow { from { opacity: .4; transform: scale(.97); } to { opacity: .75; transform: scale(1.05); } }

.g-msg { margin-top: .9rem; text-align: center; font-size: .9rem; color: var(--neg); }

/* --------------------------------------------------------------------------
   10. File rows
   -------------------------------------------------------------------------- */

.g-files { display: grid; gap: .7rem; margin-top: 1.25rem; list-style: none; padding: 0; }
.g-file {
  --ok: var(--g-lilac);
  position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: .4rem 1rem;
  padding: .85rem .9rem .85rem 1rem; border-radius: 20px;
  background: linear-gradient(180deg, rgb(255 255 255 / .06), rgb(255 255 255 / .022));
  border: 1px solid var(--g-rim-soft);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .09), 0 18px 36px -26px rgb(0 0 0 / .85);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  backdrop-filter: blur(16px) saturate(140%);
  animation: g-rise 420ms var(--ease-out) both;
}
.g-file[data-state="done"] { --ok: var(--pos); }
.g-file[data-state="error"] { --ok: var(--neg); }
.g-file[data-state="locked"], .g-file[data-state="warn"] { --ok: var(--warn); }
.g-file__doc { width: 34px; height: 42px; flex: none; }
.g-file__main { min-width: 0; }
.g-file__name { display: block; font-weight: 600; font-size: .96rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Each separator sits in the gap before its item, so one that would start a
   wrapped line hangs off the left edge and is clipped away. */
.g-file__meta { display: flex; flex-wrap: wrap; gap: .1rem 1.3rem; font-size: .82rem; color: var(--g-ink-3); font-variant-numeric: tabular-nums; clip-path: inset(-24px -24px -24px -6px); }
.g-file__meta > * { position: relative; }
.g-file__meta > * + *::before { content: "·"; position: absolute; left: -.65rem; transform: translateX(-50%); color: var(--g-ink-4); }
.g-file__status { display: inline-flex; align-items: center; gap: .45rem; color: var(--ok); font-weight: 560; }
.g-file__status::before { content: none !important; }
.g-file__end { display: flex; align-items: center; gap: .4rem; }
.g-file__body { grid-column: 1 / -1; min-width: 0; }
.g-file__body:empty { display: none; }
.g-dot { position: relative; width: 8px; height: 8px; border-radius: 50%; background: currentColor; box-shadow: 0 0 10px currentColor; flex: none; }
.g-file[data-state="working"] .g-dot { animation: g-throb 1.1s ease-in-out infinite; }
/* While working, a light runs along the row's top edge. */
.g-file::before {
  content: ""; position: absolute; top: -1px; left: 22px; right: 22px; height: 2px;
  border-radius: 2px; pointer-events: none; opacity: 0;
  background: linear-gradient(90deg, transparent, #c9bfff, transparent) 0 0 / 35% 100% no-repeat;
  box-shadow: 0 0 12px rgb(150 130 255 / .6);
  transition: opacity var(--dur-2) var(--ease);
}
.g-file[data-state="working"]::before { opacity: 1; animation: g-scan 1.4s cubic-bezier(.45, 0, .55, 1) infinite alternate; }
@keyframes g-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

.g-x {
  display: grid; place-items: center; width: 34px; height: 34px; border-radius: 10px; padding: 0;
  color: var(--g-ink-3); background: transparent; border: 1px solid transparent;
  transition: color var(--dur-1) var(--ease), background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.g-x:hover { color: var(--g-ink); background: rgb(255 255 255 / .06); border-color: var(--g-rim-soft); }
.g-x svg { width: 16px; height: 16px; }

/* --------------------------------------------------------------------------
   11. Controls
   -------------------------------------------------------------------------- */

.g-label { display: block; font-size: .86rem; font-weight: 600; color: var(--g-ink); margin-bottom: .45rem; }
.g-label small { font-weight: 450; color: var(--g-ink-3); margin-left: .35rem; }
.g-help { font-size: .82rem; color: var(--g-ink-3); margin-top: .45rem; }

.g-input {
  width: 100%; min-height: 3rem; padding: .7rem .95rem; border-radius: 14px;
  background: rgb(10 8 18 / .55); color: var(--g-ink);
  border: 1px solid rgb(255 255 255 / .1);
  box-shadow: inset 0 1px 3px rgb(0 0 0 / .55), 0 1px 0 rgb(255 255 255 / .04);
  transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
  caret-color: var(--g-lilac);
}
.g-input::placeholder { color: var(--g-ink-4); }
.g-input:hover { border-color: rgb(255 255 255 / .16); }
.g-input:focus { outline: none; border-color: rgb(179 166 255 / .6); box-shadow: inset 0 1px 3px rgb(0 0 0 / .55), 0 0 0 3px rgb(169 155 255 / .18); background: rgb(14 11 26 / .7); }
.g-input[aria-invalid="true"] { border-color: rgb(242 154 142 / .7); box-shadow: inset 0 1px 3px rgb(0 0 0 / .55), 0 0 0 3px rgb(242 154 142 / .14); }

/* An input with buttons tucked into its right edge. */
.g-inputrow { position: relative; display: flex; align-items: center; }
.g-inputrow .g-input { padding-right: calc(.6rem + var(--btns, 1) * 2.4rem); }
.g-inputrow__btns { position: absolute; right: .35rem; display: flex; gap: .15rem; }
.g-iconbtn {
  display: grid; place-items: center; width: 2.25rem; height: 2.25rem; border-radius: 10px; padding: 0;
  border: 1px solid transparent; background: transparent; color: var(--g-ink-3);
  transition: color var(--dur-1) var(--ease), background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.g-iconbtn:hover { color: var(--g-ink); background: rgb(255 255 255 / .07); border-color: var(--g-rim-soft); }
.g-iconbtn svg { width: 18px; height: 18px; }
.g-iconbtn.is-done { color: var(--pos); }

/* Segmented choice: native radios dressed as one control. */
.g-seg {
  position: relative; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  padding: 4px; border-radius: 16px;
  background: rgb(10 8 18 / .55); border: 1px solid rgb(255 255 255 / .08);
  box-shadow: inset 0 1px 3px rgb(0 0 0 / .55), 0 1px 0 rgb(255 255 255 / .04);
}
.g-seg label { position: relative; display: block; cursor: pointer; }
.g-seg input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.g-seg span {
  display: grid; place-items: center; gap: .1rem; height: 100%; min-height: 2.6rem; padding: .5rem .8rem; border-radius: 12px;
  text-align: center; font-size: .9rem; font-weight: 600; color: var(--g-ink-3);
  transition: color var(--dur-2) var(--ease), background var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease);
}
.g-seg small { display: block; font-size: .74rem; font-weight: 450; color: var(--g-ink-4); }
.g-seg label:hover span { color: var(--g-ink-2); }
.g-seg input:checked + span {
  color: var(--g-ink);
  background: linear-gradient(180deg, rgb(255 255 255 / .14), rgb(255 255 255 / .05));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .2), 0 0 0 1px rgb(255 255 255 / .08), 0 8px 20px -10px rgb(130 105 255 / .6);
}
.g-seg input:checked + span small { color: var(--g-ink-3); }
.g-seg input:focus-visible + span { outline: 2px solid var(--g-lilac); outline-offset: 2px; }

/* The switch: a recessed track, a violet fill when on. */
.g-switch { position: relative; display: inline-flex; align-items: center; gap: .7rem; cursor: pointer; -webkit-user-select: none; user-select: none; }
.g-switch input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.g-switch__track {
  position: relative; flex: none; width: 40px; height: 24px; border-radius: 999px;
  background: rgb(0 0 0 / .42); border: 1px solid var(--g-rim-soft);
  box-shadow: inset 0 1px 3px rgb(0 0 0 / .6);
  transition: background var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease);
}
.g-switch__thumb {
  position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%;
  background: linear-gradient(180deg, rgb(255 255 255 / .9), rgb(220 214 245 / .75));
  box-shadow: inset 0 1px 0 #fff, 0 2px 6px rgb(0 0 0 / .5);
  transition: transform 380ms var(--spring);
}
.g-switch input:checked + .g-switch__track {
  background: linear-gradient(180deg, #9d8ff9, #7262e6); border-color: rgb(175 160 255 / .5);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .3), 0 0 16px -4px rgb(130 110 255 / .7);
}
.g-switch input:checked + .g-switch__track .g-switch__thumb { transform: translateX(16px); }
.g-switch input:focus-visible + .g-switch__track { outline: 2px solid var(--g-lilac); outline-offset: 3px; }
.g-switch input:disabled + .g-switch__track { opacity: .45; }

/* A row of settings, each a label and its control, divided by hairlines. */
.g-rows { display: grid; }
.g-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .8rem 0; }
.g-row + .g-row { border-top: 1px solid var(--g-rim-faint); }
.g-row__text { min-width: 0; }
.g-row__text b { display: block; font-size: .94rem; font-weight: 600; }
.g-row__text small { display: block; font-size: .8rem; color: var(--g-ink-3); }

.g-select {
  appearance: none; min-height: 2.6rem; padding: .5rem 2.2rem .5rem .85rem; border-radius: 12px;
  background: rgb(10 8 18 / .55) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m7 10 5 5 5-5' fill='none' stroke='%23b3a6ff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right .6rem center / 16px;
  border: 1px solid rgb(255 255 255 / .1); color: var(--g-ink); font-size: .9rem; font-weight: 550;
  box-shadow: inset 0 1px 3px rgb(0 0 0 / .55);
}
.g-select:focus { outline: none; border-color: rgb(179 166 255 / .6); }
.g-select option { background: #1b1828; }

/* Disclosure: a glass summary row with a chevron. */
.g-more { border-top: 1px solid var(--g-rim-faint); }
.g-more > summary {
  display: flex; align-items: center; gap: .55rem; padding: .95rem 0 .2rem; list-style: none; cursor: pointer;
  font-size: .92rem; font-weight: 600; color: var(--g-ink-2);
  -webkit-user-select: none; user-select: none;
}
.g-more > summary::-webkit-details-marker { display: none; }
.g-more > summary:hover { color: var(--g-ink); }
.g-more > summary svg { width: 16px; height: 16px; transition: transform var(--dur-2) var(--ease-out); }
.g-more[open] > summary svg { transform: rotate(90deg); }
.g-more > summary small { margin-left: auto; font-weight: 450; color: var(--g-ink-3); }

/* --------------------------------------------------------------------------
   12. Buttons
   -------------------------------------------------------------------------- */

/* The violet button: the page's one main action. */
.g-btn {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center; gap: .6rem;
  min-height: 3.25rem; padding: .9rem 1.6rem; border-radius: 14px; border: 0;
  font-size: 1.02rem; font-weight: 640; color: #fff; text-decoration: none; white-space: nowrap;
  background: linear-gradient(180deg, #9d8ff9 0%, #7262e6 100%);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / .35),
    0 0 0 1px rgb(175 160 255 / .35),
    0 10px 26px -10px rgb(130 110 255 / .85);
  transition: transform var(--dur-1) var(--ease), box-shadow var(--dur-2) var(--ease), filter var(--dur-2) var(--ease), opacity var(--dur-2) var(--ease);
  -webkit-user-select: none; user-select: none;
}
.g-btn:hover { transform: translateY(-1px); filter: brightness(1.08); box-shadow: inset 0 1px 0 rgb(255 255 255 / .4), 0 0 0 1px rgb(190 178 255 / .5), 0 14px 30px -10px rgb(130 110 255 / .95); }
.g-btn:active { transform: translateY(0) scale(.98); }
.g-btn:disabled, .g-btn[aria-disabled="true"] { opacity: .42; cursor: default; pointer-events: none; filter: saturate(.5); }
.g-btn svg { width: 20px; height: 20px; flex: none; }
.g-btn--block { width: 100%; }
.g-btn--lg { min-height: 3.6rem; font-size: 1.08rem; border-radius: 16px; }

/* The glass button: everything that isn't the main action. */
.g-btn--glass {
  color: var(--g-ink);
  background: linear-gradient(180deg, rgb(255 255 255 / .09), rgb(255 255 255 / .03));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .12), 0 0 0 1px var(--g-rim);
}
.g-btn--glass:hover { filter: none; background: linear-gradient(180deg, rgb(255 255 255 / .13), rgb(255 255 255 / .05)); box-shadow: inset 0 1px 0 rgb(255 255 255 / .16), 0 0 0 1px rgb(255 255 255 / .24); }
.g-btn--sm { min-height: 2.4rem; padding: .5rem .95rem; font-size: .88rem; border-radius: 11px; gap: .45rem; }
.g-btn--sm svg { width: 16px; height: 16px; }

/* Saved: a green wash, and a tick that draws in. */
.g-btn::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(180deg, #4fd296 0%, #2e9f6c 100%);
  opacity: 0; transition: opacity 420ms var(--ease);
}
.g-btn > * { position: relative; }
.g-btn.is-saved::before { opacity: 1; }
.g-btn.is-saved { box-shadow: inset 0 1px 0 rgb(255 255 255 / .35), 0 0 0 1px rgb(120 230 175 / .45), 0 10px 26px -10px rgb(70 200 140 / .9); }
.g-spin { width: 20px; height: 20px; animation: g-spin .8s linear infinite; }
.g-ripple {
  position: absolute; border-radius: 50%; pointer-events: none;
  background: radial-gradient(closest-side, rgb(255 255 255 / .45), rgb(255 255 255 / 0));
  transform: scale(0); animation: g-ripple 620ms var(--ease-out) forwards;
}

.g-link {
  display: inline-flex; align-items: center; gap: .4rem; padding: 0; border: 0; background: none;
  font-size: .9rem; font-weight: 550; color: var(--g-ink-2); text-decoration: none; cursor: pointer;
}
.g-link:hover { color: var(--g-ink); }
.g-link svg { width: 16px; height: 16px; transition: transform var(--dur-3) var(--ease-out); }
.g-link--restart:hover svg { transform: rotate(-180deg); }

/* --------------------------------------------------------------------------
   13. Small things
   -------------------------------------------------------------------------- */

.g-chip {
  display: inline-flex; align-items: center; gap: .35rem; padding: .22rem .6rem; border-radius: 999px;
  font-size: .76rem; font-weight: 600; color: var(--g-ink-2);
  background: rgb(255 255 255 / .05); border: 1px solid var(--g-rim-soft);
}
.g-chip--ok { color: var(--pos); background: rgb(126 226 168 / .08); border-color: rgb(126 226 168 / .28); }
.g-chip--warn { color: var(--warn); background: rgb(246 193 119 / .08); border-color: rgb(246 193 119 / .3); }
.g-chip--bad { color: var(--neg); background: rgb(242 154 142 / .08); border-color: rgb(242 154 142 / .3); }
.g-chip--violet { color: var(--g-lilac); background: rgb(179 166 255 / .09); border-color: rgb(179 166 255 / .32); }
.g-chip svg { width: 12px; height: 12px; }
a.g-chip { text-decoration: none; transition: filter .15s; }
a.g-chip:hover { filter: brightness(1.2); }

.g-badge {
  display: inline-flex; align-items: center; padding: .1rem .45rem; border-radius: 6px;
  font-size: .64rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--g-lilac); background: rgb(179 166 255 / .1); border: 1px solid rgb(179 166 255 / .32);
}
.g-badge--soon { color: var(--g-ink-3); background: rgb(255 255 255 / .04); border-color: var(--g-rim-soft); }
.g-badge--new { color: #120f1f; background: linear-gradient(180deg, #d2c9ff, #a99bff); border-color: transparent; }

.g-note {
  padding: 1rem 1.15rem; border-radius: 18px; font-size: .88rem; color: var(--g-ink-2);
  background: rgb(255 255 255 / .03); border: 1px solid var(--g-rim-soft);
}
.g-note b, .g-note strong { color: var(--g-ink); font-weight: 600; }
.g-note--warn { border-color: rgb(246 193 119 / .28); background: rgb(246 193 119 / .05); }
.g-note--warn b { color: var(--warn); }

.g-kbd {
  display: inline-grid; place-items: center; min-width: 1.5rem; height: 1.5rem; padding: 0 .35rem; border-radius: 6px;
  font: 600 .72rem/1 var(--font); color: var(--g-ink-3);
  background: rgb(255 255 255 / .05); border: 1px solid var(--g-rim-soft); box-shadow: 0 1px 0 rgb(255 255 255 / .06);
}

/* The working progress groove. */
.g-progress { height: 4px; border-radius: 999px; overflow: hidden; background: rgb(0 0 0 / .35); box-shadow: inset 0 1px 2px rgb(0 0 0 / .5); }
.g-progress i { display: block; height: 100%; width: 0; border-radius: inherit; background: linear-gradient(90deg, #7262e6, #b3a6ff); box-shadow: 0 0 12px rgb(150 130 255 / .6); transition: width var(--dur-2) var(--ease-out); }

/* A toast above everything: short news, then gone. */
.g-toast {
  position: fixed; left: 50%; bottom: 1.5rem; z-index: 400; transform: translate(-50%, 20px);
  padding: .7rem 1.1rem; border-radius: 14px; font-size: .9rem; font-weight: 550; opacity: 0; pointer-events: none;
  background: linear-gradient(180deg, rgb(44 40 64 / .95), rgb(26 23 38 / .96));
  border: 1px solid rgb(255 255 255 / .14);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .12), 0 20px 50px -20px rgb(0 0 0 / .9);
  transition: opacity var(--dur-2) var(--ease), transform var(--dur-2) var(--ease-out);
}
.g-toast.is-shown { opacity: 1; transform: translate(-50%, 0); }

/* --------------------------------------------------------------------------
   Page grids — thumbnails to reorder, turn, remove and pick (pagegrid.js)
   -------------------------------------------------------------------------- */

.g-pages {
  --tile: 9.75rem;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--tile), 1fr)); gap: 1rem .9rem;
  list-style: none; padding: 0; margin: 0;
}
.g-page { position: relative; display: grid; gap: .45rem; justify-items: center; border-radius: 18px; outline: none; touch-action: manipulation; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.g-page__frame {
  position: relative; display: grid; place-items: center; width: 100%; aspect-ratio: 3 / 4; border-radius: 16px; cursor: grab;
  background: linear-gradient(180deg, rgb(255 255 255 / .06), rgb(255 255 255 / .02));
  border: 1px solid var(--g-rim-soft);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .08), 0 14px 30px -22px rgb(0 0 0 / .9);
  transition: border-color var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease), background var(--dur-2) var(--ease);
}
.g-page__canvas {
  border-radius: 3px; background: rgb(255 255 255 / .06);
  box-shadow: 0 0 0 1px rgb(0 0 0 / .25), 0 10px 24px -10px rgb(0 0 0 / .8);
  opacity: 0; transition: opacity 360ms var(--ease);
}
.g-page:not(.is-drawn) .g-page__canvas { width: 64%; aspect-ratio: 1 / 1.3; opacity: 1; background: linear-gradient(100deg, #1d1a28 30%, #2c2840 50%, #1d1a28 70%) 0 0 / 250% 100%; animation: g-shimmer 1.4s linear infinite; }
.g-page.is-drawn .g-page__canvas { opacity: 1; }
.g-page.is-failed .g-page__canvas { animation: none; }
.g-page__label { font-size: .8rem; font-weight: 600; color: var(--g-ink-3); font-variant-numeric: tabular-nums; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.g-page:hover .g-page__frame, .g-page:focus-visible .g-page__frame { border-color: rgb(179 166 255 / .35); background: linear-gradient(180deg, rgb(255 255 255 / .09), rgb(255 255 255 / .03)); }
.g-page:focus-visible .g-page__frame { box-shadow: 0 0 0 2px var(--g-lilac), 0 14px 30px -22px rgb(0 0 0 / .9); }

/* Which file a page came from, as a coloured number in its corner. */
.g-page__badge {
  position: absolute; left: 8px; top: 8px; min-width: 1.4rem; height: 1.4rem; padding: 0 .35rem; border-radius: 7px;
  display: grid; place-items: center; font-size: .7rem; font-weight: 700; color: #120f1f;
  background: var(--b, var(--g-lilac)); box-shadow: 0 4px 10px -4px rgb(0 0 0 / .7);
}

/* The tools appear over the page on hover or focus, always on touch. */
.g-page__tools {
  position: absolute; right: 6px; top: 6px; display: flex; flex-direction: column; gap: 4px;
  opacity: 0; transform: translateX(4px); transition: opacity var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.g-page:hover .g-page__tools, .g-page:focus-within .g-page__tools { opacity: 1; transform: none; }
@media (hover: none) { .g-page__tools { opacity: 1; transform: none; } }
.g-page__tool {
  display: grid; place-items: center; width: 30px; height: 30px; padding: 0; border-radius: 9px;
  color: var(--g-ink); background: rgb(24 21 36 / .82); border: 1px solid rgb(255 255 255 / .14);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  box-shadow: 0 6px 14px -8px rgb(0 0 0 / .9);
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.g-page__tool svg { width: 15px; height: 15px; }
.g-page__tool:hover { background: rgb(60 52 96 / .9); border-color: rgb(179 166 255 / .45); }
.g-page__tool--bad:hover { background: rgb(110 40 44 / .9); border-color: rgb(242 154 142 / .55); color: #ffd9d3; }

/* Picking pages: a tick in the corner and a lilac rim. */
.g-page__tick {
  position: absolute; right: 8px; bottom: 8px; display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%;
  color: transparent; background: rgb(14 12 22 / .7); border: 1.5px solid rgb(255 255 255 / .35);
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.g-page__tick svg { width: 14px; height: 14px; }
.g-page.is-selected .g-page__tick { color: #fff; background: linear-gradient(180deg, #9d8ff9, #7262e6); border-color: transparent; }
.g-page.is-selected .g-page__frame { border-color: rgb(179 166 255 / .7); background: linear-gradient(180deg, rgb(169 155 255 / .2), rgb(114 98 230 / .08)); box-shadow: inset 0 0 0 1px rgb(179 166 255 / .35), 0 0 30px -12px rgb(130 105 255 / .8); }
.g-pages[data-picking] .g-page__frame { cursor: pointer; }
.g-pages:not([data-picking]) .g-page__tick { display: none; }
.g-pages:not([data-picking]) .g-page.is-selected .g-page__frame { border-color: var(--g-rim-soft); background: linear-gradient(180deg, rgb(255 255 255 / .06), rgb(255 255 255 / .02)); box-shadow: inset 0 1px 0 rgb(255 255 255 / .08), 0 14px 30px -22px rgb(0 0 0 / .9); }
.g-pages[data-static] .g-page__frame { cursor: default; }
/* Pages a choice leaves out. */
.g-page.is-dim .g-page__frame { opacity: .4; filter: saturate(.35); }
.g-page.is-dim .g-page__label { opacity: .5; }

/* Lifted while dragging: above the rest, a little larger, no transition
   fighting the pointer. */
.g-page.is-lifted { z-index: 20; pointer-events: none; transition: none; }
.g-page.is-lifted .g-page__frame { cursor: grabbing; border-color: rgb(179 166 255 / .6); box-shadow: 0 30px 60px -20px rgb(0 0 0 / .95), 0 0 40px -10px rgb(130 105 255 / .7); }
.g-pages.is-sorting, .g-pages.is-sorting * { cursor: grabbing !important; }

@media (max-width: 560px) { .g-pages { --tile: 7.25rem; gap: .8rem .6rem; } }
@media (prefers-reduced-motion: reduce) { .g-page:not(.is-drawn) .g-page__canvas { animation: none; } }

/* A workbench: the pages on the left, the settings beside them, sticky,
   so the main button is always in reach. Stacked on narrow screens with
   the settings first. */
.g-bench { display: grid; grid-template-columns: minmax(0, 1fr) 21rem; gap: 1.25rem; align-items: start; margin-top: 1.25rem; }
.g-bench__side { position: sticky; top: 1rem; display: grid; gap: 1rem; padding: 1.15rem; max-height: calc(100dvh - 2rem); overflow: auto; }
.g-bench__side h2 { font-size: 1.05rem; }
.g-bench__side .g-seg { grid-auto-flow: row; grid-auto-columns: auto; grid-template-columns: 1fr 1fr; }
.g-bench__side .g-seg span { min-height: 2.5rem; font-size: .86rem; }
.g-bench__main { min-width: 0; }
.g-bench__file { display: flex; align-items: center; gap: .75rem; margin-bottom: 1rem; min-width: 0; }
.g-bench__file b { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.g-bench__file small { display: block; font-size: .82rem; color: var(--g-ink-3); }
.g-bench__actions { display: flex; flex-wrap: wrap; gap: .4rem; }
@media (max-width: 900px) {
  .g-bench { grid-template-columns: 1fr; }
  .g-bench__side { position: static; max-height: none; order: -1; }
}

/* A large page preview with page steps under it (the stamping tools). */
.g-preview { display: grid; justify-items: center; gap: .8rem; }
.g-preview canvas { border-radius: 4px; box-shadow: 0 0 0 1px rgb(0 0 0 / .3), 0 30px 60px -24px rgb(0 0 0 / .9), 0 0 60px -20px rgb(130 105 255 / .35); background: #fff; }
.g-preview__nav { display: flex; align-items: center; gap: .6rem; font-size: .86rem; color: var(--g-ink-2); font-variant-numeric: tabular-nums; }
.g-preview__nav button {
  display: grid; place-items: center; width: 34px; height: 34px; border-radius: 10px; padding: 0;
  color: var(--g-ink-2); background: rgb(255 255 255 / .05); border: 1px solid var(--g-rim-soft);
}
.g-preview__nav button:hover:not(:disabled) { color: #fff; border-color: rgb(179 166 255 / .45); }
.g-preview__nav button:disabled { opacity: .35; cursor: default; }
.g-preview__nav svg { width: 16px; height: 16px; }

/* Where on the page: a grid of radio squares, each with a dot where it
   puts the thing. */
.g-pos { display: grid; grid-template-columns: repeat(3, 2.6rem); gap: .3rem; padding: .35rem; width: max-content; border-radius: 14px; background: rgb(10 8 18 / .55); border: 1px solid rgb(255 255 255 / .08); box-shadow: inset 0 1px 3px rgb(0 0 0 / .55); }
.g-pos label { position: relative; display: block; cursor: pointer; }
.g-pos input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.g-pos span { display: grid; height: 2.1rem; border-radius: 9px; border: 1px solid transparent; transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease); }
.g-pos span::after { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--g-ink-4); align-self: var(--v, center); justify-self: var(--h, center); margin: 6px; transition: background var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease); }
.g-pos label:hover span { background: rgb(255 255 255 / .05); }
.g-pos input:checked + span { background: linear-gradient(180deg, rgb(169 155 255 / .3), rgb(114 98 230 / .18)); border-color: rgb(179 166 255 / .5); }
.g-pos input:checked + span::after { background: #fff; box-shadow: 0 0 10px rgb(179 166 255 / .9); }
.g-pos input:focus-visible + span { outline: 2px solid var(--g-lilac); outline-offset: 1px; }

/* A labelled slider with its value. */
.g-slider { display: grid; gap: .3rem; }
.g-slider label { display: flex; justify-content: space-between; gap: 1rem; font-size: .86rem; font-weight: 600; }
.g-slider output { color: var(--g-lilac); font-variant-numeric: tabular-nums; font-weight: 600; }

.g-swatches { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.g-swatches button { width: 26px; height: 26px; border-radius: 50%; padding: 0; border: 2px solid rgb(255 255 255 / .2); background: var(--sw); box-shadow: 0 2px 6px rgb(0 0 0 / .4); }
.g-swatches button[aria-pressed="true"] { border-color: #fff; box-shadow: 0 0 0 2px rgb(179 166 255 / .6); }
.g-swatches input[type="color"] { width: 34px; height: 28px; border-radius: 8px; padding: 2px; }

/* A row of controls over a page grid. */
.g-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin: 1.25rem 0 1rem; }
.g-toolbar__spacer { flex: 1 1 auto; }
.g-toolbar .g-seg { grid-auto-columns: auto; }
.g-toolbar .g-seg span { min-height: 2.3rem; padding: .35rem .9rem; font-size: .86rem; }
.g-count { font-size: .86rem; color: var(--g-ink-3); font-variant-numeric: tabular-nums; }

/* A modal glass card over a blurred, darkened page. */
.g-dialog { width: min(26rem, calc(100vw - 2rem)); padding: 0; margin: auto; border: 0; background: none; color: var(--g-ink); overflow: visible; }
.g-dialog::backdrop { background: rgb(8 6 16 / .62); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }
.g-dialog[open] { animation: g-dialog-in 360ms cubic-bezier(.33, 1, .68, 1); }
.g-dialog[open]::backdrop { animation: g-fade 300ms ease-out; }
@keyframes g-dialog-in { from { opacity: 0; transform: translateY(10px) scale(.97); } to { opacity: 1; transform: none; } }
.g-dialog__card {
  display: grid; gap: .85rem; padding: 1.5rem; border-radius: 26px; text-align: left;
  background: linear-gradient(180deg, rgb(40 36 58 / .94), rgb(22 20 32 / .96));
  border: 1px solid rgb(255 255 255 / .14);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .14), 0 40px 90px -30px rgb(0 0 0 / .9), 0 0 70px -24px rgb(130 105 255 / .55);
}
.g-dialog__card h2 { font-size: 1.2rem; }
.g-dialog__card p { font-size: .9rem; color: var(--g-ink-2); }
.g-dialog__card p b { color: var(--g-ink); font-weight: 600; overflow-wrap: anywhere; }
.g-dialog__err { color: var(--neg) !important; font-size: .84rem !important; margin-top: -.3rem; }
.g-dialog__actions { display: flex; justify-content: flex-end; gap: .6rem; margin-top: .3rem; }
.g-dialog__actions .g-btn { min-height: 2.8rem; padding: .6rem 1.2rem; font-size: .95rem; }

/* --------------------------------------------------------------------------
   14. Results and what's next
   -------------------------------------------------------------------------- */

.g-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .7rem; margin-top: 1.25rem; }
.g-actions__spacer { flex: 1 1 auto; }

.g-next { margin-top: 1.75rem; }
.g-next h2 { font-size: .8rem; font-weight: 650; letter-spacing: .08em; text-transform: uppercase; color: var(--g-ink-3); margin-bottom: .7rem; }
.g-next__list { display: flex; flex-wrap: wrap; gap: .55rem; list-style: none; padding: 0; }
.g-next__list a, .g-next__list button {
  display: inline-flex; align-items: center; gap: .55rem; padding: .4rem .85rem .4rem .45rem; border-radius: 14px;
  font-size: .88rem; font-weight: 560; color: var(--g-ink-2); text-decoration: none;
  background: linear-gradient(180deg, rgb(255 255 255 / .07), rgb(255 255 255 / .025));
  border: 1px solid var(--g-rim-soft);
  transition: color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.g-next__list a:hover, .g-next__list button:hover { color: var(--g-ink); border-color: rgb(179 166 255 / .35); transform: translateY(-1px); }
.g-next__list .g-icon { --size: 28px; --r: 9px; }

/* The finished file: a tick, what it is, a big download, where next. */
.g-result { margin-top: 1.25rem; padding: clamp(1.1rem, 3vw, 1.5rem); animation: g-rise 480ms var(--ease-out) both; }
.g-result__main { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 1.25rem; }
.g-result__tick {
  display: grid; place-items: center; width: 52px; height: 52px; border-radius: 16px; flex: none; color: #0f2a1d;
  background: linear-gradient(180deg, #a8f0c8, #4fd296); box-shadow: inset 0 1px 0 rgb(255 255 255 / .5), 0 12px 28px -12px rgb(70 200 140 / .8);
}
.g-result__tick svg { width: 26px; height: 26px; }
.g-result__text { flex: 1 1 14rem; min-width: 0; }
.g-result__text h2 { font-size: 1.2rem; }
.g-result__text p { font-size: .9rem; color: var(--g-ink-3); overflow-wrap: anywhere; }
.g-result__text b { color: var(--g-ink-2); font-weight: 600; }
.g-result__list { list-style: none; padding: 0; margin: 1.1rem 0 0; display: grid; gap: 1px; max-height: 22rem; overflow: auto; border-radius: 14px; background: rgb(255 255 255 / .04); }
.g-result__list li { display: flex; align-items: center; gap: .5rem 1rem; padding: .55rem .6rem .55rem .9rem; background: rgb(14 12 22 / .45); }
.g-result__name { flex: 1 1 auto; min-width: 0; font-size: .9rem; font-weight: 560; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.g-result__facts { font-size: .8rem; color: var(--g-ink-3); white-space: nowrap; font-variant-numeric: tabular-nums; }
@media (max-width: 560px) { .g-result__facts { display: none; } .g-result__list .g-btn [data-label] { display: none; } }
.g-result__next { margin-top: 1.1rem; padding-top: 1rem; border-top: 1px solid var(--g-rim-faint); }
.g-result__next h3 { font-size: .78rem; font-weight: 650; letter-spacing: .08em; text-transform: uppercase; color: var(--g-ink-3); margin-bottom: .6rem; }
@media (max-width: 560px) { .g-result__main .g-btn { width: 100%; } }

/* Explainers under a tool: two or three glass notes in a row. */
.g-explain { display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: 1rem; margin-top: clamp(2rem, 5vw, 3rem); }
.g-explain article { padding: 1.15rem 1.25rem; }
.g-explain h3 { font-size: 1rem; margin-bottom: .4rem; display: flex; align-items: center; gap: .55rem; }
.g-explain h3 svg { width: 18px; height: 18px; color: var(--g-lilac); flex: none; }
.g-explain p { font-size: .88rem; color: var(--g-ink-2); }
.g-explain p + p { margin-top: .5rem; }

/* --------------------------------------------------------------------------
   15. Footer
   -------------------------------------------------------------------------- */

.g-foot { margin-top: clamp(3rem, 8vw, 5rem); padding: 0 0 1.5rem; }
.g-foot__bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: .75rem 1.5rem;
  padding: 1rem 1.25rem; border-radius: 20px; font-size: .84rem; color: var(--g-ink-3);
  background: linear-gradient(180deg, rgb(255 255 255 / .05), rgb(255 255 255 / .02));
  border: 1px solid var(--g-rim-faint);
}
.g-foot__bar a { color: var(--g-ink-2); text-decoration: none; }
.g-foot__bar a:hover { color: var(--g-ink); }
.g-foot__bar nav { display: flex; flex-wrap: wrap; gap: .5rem 1.25rem; margin-left: auto; }

/* --------------------------------------------------------------------------
   16. Base pieces the older tools were built on

   The compressor, extractor and editor began as Labs pages on the site's
   stylesheet, and their own glass styles were written on top of its
   buttons, fields and range inputs. Those bases are here, in glass, so
   the tools look as they were designed without main.css.
   -------------------------------------------------------------------------- */

:root { --font-sans: var(--font); --font-mono: var(--mono); --ink: var(--g-ink); }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  padding: .75rem 1.25rem; border-radius: 999px;
  border: 1px solid var(--g-rim); background: rgb(255 255 255 / .05); color: var(--g-ink);
  font-size: .94rem; font-weight: 560; text-decoration: none;
  transition: transform var(--dur-1) var(--ease), background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.btn:hover { background: rgb(255 255 255 / .1); transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn--sm { padding: .45rem .85rem; font-size: .84rem; }

.field { display: grid; gap: .35rem; min-width: 8rem; }
.field__label { font-size: .78rem; font-weight: 600; letter-spacing: .02em; color: var(--g-ink-3); }
.field__value { color: var(--g-lilac); }

input[type="range"] { -webkit-appearance: none; appearance: none; width: 100%; height: 1.5rem; background: transparent; }
input[type="range"]::-webkit-slider-runnable-track { height: 4px; border-radius: 999px; background: rgb(0 0 0 / .42); box-shadow: inset 0 1px 2px rgb(0 0 0 / .5); }
input[type="range"]::-moz-range-track { height: 4px; border-radius: 999px; background: rgb(0 0 0 / .42); }
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 1.1rem; height: 1.1rem; margin-top: -.43rem; border-radius: 50%; cursor: grab;
  background: linear-gradient(180deg, #fff, #d9d2ff); border: 0; box-shadow: 0 0 0 4px rgb(169 155 255 / .25), 0 2px 6px rgb(0 0 0 / .5);
  transition: transform var(--dur-1) var(--ease);
}
input[type="range"]::-moz-range-thumb { width: 1.1rem; height: 1.1rem; border-radius: 50%; cursor: grab; background: linear-gradient(180deg, #fff, #d9d2ff); border: 0; box-shadow: 0 0 0 4px rgb(169 155 255 / .25), 0 2px 6px rgb(0 0 0 / .5); }
input[type="range"]:hover::-webkit-slider-thumb { transform: scale(1.1); }

input[type="number"], input[type="text"], select, textarea {
  width: 100%; padding: .5rem .65rem; border-radius: 10px; font-size: .92rem;
  background: rgb(10 8 18 / .55); border: 1px solid rgb(255 255 255 / .12);
}
input:disabled, select:disabled, textarea:disabled { opacity: .45; cursor: not-allowed; }
input[type="color"] { width: 3rem; height: 2.2rem; padding: 2px; background: rgb(10 8 18 / .55); border: 1px solid rgb(255 255 255 / .12); border-radius: 8px; }
input[type="file"] { max-width: 100%; }

/* --------------------------------------------------------------------------
   17. Shared keyframes, motion preferences, small screens
   -------------------------------------------------------------------------- */

@keyframes g-scan { from { background-position: 0 0; } to { background-position: 100% 0; } }
@keyframes g-shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }
@keyframes g-spin { to { transform: rotate(360deg); } }
@keyframes g-throb { 0%, 100% { transform: scale(.75); opacity: .55; } 50% { transform: scale(1.15); opacity: 1; } }
@keyframes g-ripple { to { transform: scale(1); opacity: 0; } }
@keyframes g-fade { from { opacity: 0; } to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .g-aura i, .g-fl, .g-corner, .g-file, .g-file::before, .g-dot { animation: none !important; }
  .g-drop.is-over .g-corner, .g-drop:hover .g-drop__art svg { transform: none; }
  .g-menu, .g-toast, .g-btn, .g-switch__thumb { transition: none; }
  * { scroll-behavior: auto !important; }
}

@media (max-width: 560px) {
  .g-bezel { border-radius: 30px; padding: 7px; }
  .g-drop { border-radius: 24px; min-height: 15.5rem; padding: 2rem 1rem 1.6rem; }
  .g-drop.is-collapsed { padding: .85rem 1rem; justify-content: start; }
  .g-drop__compact { justify-content: flex-start; }
  .g-corner { width: 24px; height: 24px; }
  .g-corner--tl, .g-corner--tr { top: 16px; }
  .g-corner--bl, .g-corner--br { bottom: 16px; }
  .g-corner--tl, .g-corner--bl { left: 16px; }
  .g-corner--tr, .g-corner--br { right: 16px; }
  .g-file { gap: .4rem .7rem; padding: .8rem .6rem .8rem .85rem; }
  .g-file__end { gap: .2rem; }
  /* The row's own download shrinks to its icon. */
  .g-file__end .g-btn--sm { padding: .5rem .62rem; }
  .g-file__end .g-btn--sm [data-label] { display: none; }
  .g-more > summary small { display: none; }
  .g-foot__bar nav { margin-left: 0; }
}
