/* ==========================================================================
   ZappoPDF — design system

   Principles this file is built on:
     1. Space is the primary design tool. Everything comes from one 4px scale.
     2. One accent colour. Category colour is a quiet signal, never decoration.
     3. Type has a real scale and a measured line length (~68ch for prose).
     4. Borders do the structural work; shadows only appear on interaction.
     5. Motion is short, eased, and always optional.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* -- neutral ramp (slightly cool) -- */
  --n-0:   #ffffff;
  --n-25:  #fcfcfe;
  --n-50:  #f7f8fb;
  --n-100: #f0f2f7;
  --n-150: #e7eaf2;
  --n-200: #dde1eb;
  --n-300: #c6ccdb;
  --n-400: #666f88;
  --n-500: #5f6780;
  --n-600: #4d556a;
  --n-700: #353c4d;
  --n-800: #222736;
  --n-900: #131722;

  /* -- brand -- */
  --brand-50:  #f3f1ff;
  --brand-100: #e8e4ff;
  --brand-200: #cfc6ff;
  --brand-300: #ab9cff;
  --brand-500: #5b3df5;
  --brand-600: #4b2ce4;
  --brand-700: #3d21c0;

  /* -- semantic surfaces -- */
  --bg:          var(--n-50);
  --surface:     var(--n-0);
  --surface-2:   var(--n-100);
  --surface-3:   var(--n-150);
  --border:      var(--n-200);
  --border-soft: var(--n-150);
  --border-firm: var(--n-300);

  --text:   var(--n-900);
  --text-2: var(--n-600);
  --muted:  var(--n-500);
  --faint:  var(--n-400);

  --primary:       var(--brand-500);
  --primary-hover: var(--brand-600);
  --primary-deep:  var(--brand-700);
  --primary-tint:  var(--brand-50);
  --primary-line:  var(--brand-200);
  --on-primary:    #ffffff;

  --success:      #0f8f5f;
  --success-tint: #e7f6ef;
  --danger:       #d32a52;
  --danger-tint:  #fdecf0;
  --warn:         #b4700a;
  --warn-tint:    #fdf3e0;

  /* Category hues, used as tinted icon chips — never as solid blocks. */
  --cat-organize: #5b3df5;
  --cat-optimize: #0f8f5f;
  --cat-convert:  #0b7fc4;
  --cat-edit:     #b4700a;
  --cat-security: #d32a52;
  --cat-tint: 11%;

  /* -- space (4px base) -- */
  --s1: 4px;   --s2: 8px;   --s3: 12px;  --s4: 16px;
  --s5: 20px;  --s6: 24px;  --s7: 32px;  --s8: 40px;
  --s9: 48px;  --s10: 64px; --s11: 80px; --s12: 96px; --s13: 128px;

  /* -- type -- */
  --t-xs:  0.75rem;    --t-sm:  0.8125rem; --t-base: 0.9375rem;
  --t-md:  1rem;       --t-lg:  1.125rem;  --t-xl:   1.3125rem;
  --t-2xl: 1.625rem;   --t-3xl: 2.125rem;  --t-4xl:  2.75rem;

  --lh-tight: 1.15;
  --lh-snug:  1.35;
  --lh-body:  1.65;

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

  /* -- radius -- */
  --r-xs: 6px; --r-sm: 9px; --r-md: 12px; --r-lg: 16px; --r-xl: 22px; --r-full: 999px;

  /* -- elevation: flat at rest, lifts only on interaction -- */
  --sh-1: 0 1px 2px rgba(19, 23, 34, .05);
  --sh-2: 0 2px 4px rgba(19, 23, 34, .04), 0 8px 20px rgba(19, 23, 34, .06);
  --sh-3: 0 14px 40px rgba(19, 23, 34, .12), 0 3px 10px rgba(19, 23, 34, .06);
  --ring: 0 0 0 3px color-mix(in srgb, var(--primary) 26%, transparent);

  /* -- motion -- */
  --ease: cubic-bezier(.2, .7, .3, 1);
  --fast: 120ms;
  --med:  200ms;

  /* -- layout -- */
  --header-h: 68px;
  --maxw: 1320px;
  --measure: 68ch;
}

/* Dark: a distinct ramp, not an inversion. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --n-0:   #171b28;
    --n-25:  #151926;
    --n-50:  #0f1219;
    --n-100: #1d2231;
    --n-150: #262c3d;
    --n-200: #2f3648;
    --n-300: #3d4557;
    --n-400: #838ca6;
    --n-500: #8b93a9;
    --n-600: #aeb5c7;
    --n-700: #cdd3e0;
    --n-800: #e4e8f0;
    --n-900: #f2f4f9;

    --brand-50:  #1c1a3a;
    --brand-100: #241f4d;
    --brand-200: #3a3172;
    --brand-300: #6f5cf0;
    --brand-500: #8b74ff;
    --brand-600: #9d89ff;
    --brand-700: #b3a3ff;

    --success:      #3ecb95;
    --success-tint: #102a20;
    --danger:       #ff6f8d;
    --danger-tint:  #2d1620;
    --warn:         #e5a83c;
    --warn-tint:    #2c2110;

    --cat-organize: #8b74ff;
    --cat-optimize: #3ecb95;
    --cat-convert:  #4bb2f0;
    --cat-edit:     #e5a83c;
    --cat-security: #ff6f8d;
    --cat-tint: 17%;

    --on-primary: #12101f;

    --sh-1: 0 1px 2px rgba(0, 0, 0, .40);
    --sh-2: 0 2px 6px rgba(0, 0, 0, .40), 0 10px 24px rgba(0, 0, 0, .34);
    --sh-3: 0 18px 48px rgba(0, 0, 0, .55), 0 4px 12px rgba(0, 0, 0, .40);
  }
}

:root[data-theme="dark"] {
  --n-0:   #171b28;
  --n-25:  #151926;
  --n-50:  #0f1219;
  --n-100: #1d2231;
  --n-150: #262c3d;
  --n-200: #2f3648;
  --n-300: #3d4557;
  --n-400: #838ca6;
  --n-500: #8b93a9;
  --n-600: #aeb5c7;
  --n-700: #cdd3e0;
  --n-800: #e4e8f0;
  --n-900: #f2f4f9;

  --brand-50:  #1c1a3a;
  --brand-100: #241f4d;
  --brand-200: #3a3172;
  --brand-300: #6f5cf0;
  --brand-500: #8b74ff;
  --brand-600: #9d89ff;
  --brand-700: #b3a3ff;

  --success:      #3ecb95;
  --success-tint: #102a20;
  --danger:       #ff6f8d;
  --danger-tint:  #2d1620;
  --warn:         #e5a83c;
  --warn-tint:    #2c2110;

  --cat-organize: #8b74ff;
  --cat-optimize: #3ecb95;
  --cat-convert:  #4bb2f0;
  --cat-edit:     #e5a83c;
  --cat-security: #ff6f8d;
  --cat-tint: 17%;

  --on-primary: #12101f;

  --sh-1: 0 1px 2px rgba(0, 0, 0, .40);
  --sh-2: 0 2px 6px rgba(0, 0, 0, .40), 0 10px 24px rgba(0, 0, 0, .34);
  --sh-3: 0 18px 48px rgba(0, 0, 0, .55), 0 4px 12px rgba(0, 0, 0, .40);
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + var(--s6));
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--t-md);
  line-height: var(--lh-body);
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img, svg, canvas, video { max-width: 100%; display: block; }

h1, h2, h3, h4 {
  margin: 0 0 var(--s3);
  line-height: var(--lh-tight);
  font-weight: 640;
  letter-spacing: -0.021em;
  color: var(--text);
  text-wrap: balance;
}
h1 { font-size: var(--t-4xl); letter-spacing: -0.032em; }
h2 { font-size: var(--t-2xl); letter-spacing: -0.026em; }
h3 { font-size: var(--t-lg); }
h4 { font-size: var(--t-md); }

p { margin: 0 0 var(--s4); }
a { color: var(--primary); text-decoration: none; text-underline-offset: 3px; }
a:hover { text-decoration: underline; }
ul, ol { padding-left: var(--s5); margin: 0 0 var(--s4); }
li { margin-bottom: var(--s2); }
hr { border: 0; border-top: 1px solid var(--border); margin: var(--s9) 0; }
strong, b { font-weight: 620; color: var(--text); }
small { font-size: var(--t-sm); }

:focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--r-xs); }
::selection { background: color-mix(in srgb, var(--primary) 22%, transparent); }

/* --------------------------------------------------------------------------
   3. Layout primitives
   -------------------------------------------------------------------------- */
.wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 var(--s6); }
.narrow { max-width: 780px; }
.center { text-align: center; }
.muted { color: var(--muted); }
.small { font-size: var(--t-base); }
.mono { font-family: var(--mono); font-size: .875em; letter-spacing: -.01em; }
.hidden { display: none !important; }

.section { padding: var(--s12) 0; }
.section-head { margin-bottom: var(--s8); max-width: 640px; }
.section-head.center { margin-left: auto; margin-right: auto; }
.section-head h2 { margin-bottom: var(--s3); }
.section-head p { color: var(--muted); font-size: var(--t-lg); margin: 0; line-height: var(--lh-snug); }

.eyebrow {
  display: block; margin-bottom: var(--s3);
  font-size: var(--t-xs); font-weight: 680; letter-spacing: .13em;
  text-transform: uppercase; color: var(--primary);
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: -9999px; top: var(--s2); z-index: 200;
  background: var(--primary); color: var(--on-primary);
  padding: var(--s3) var(--s5); border-radius: var(--r-sm); font-weight: 600;
}
.skip-link:focus { left: var(--s4); }

@media (max-width: 720px) {
  .section { padding: var(--s10) 0; }
  .wrap { padding: 0 var(--s5); }
}

/* --------------------------------------------------------------------------
   4. Header
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky; top: 0; z-index: 60; height: var(--header-h);
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  border-bottom: 1px solid var(--border-soft);
}
.site-header .wrap { display: flex; align-items: center; gap: var(--s2); height: 100%; }

.brand {
  display: flex; align-items: center; gap: var(--s3);
  font-weight: 680; font-size: 1.0625rem; letter-spacing: -.03em; color: var(--text);
}
.brand:hover { text-decoration: none; }
.brand-mark {
  width: 30px; height: 30px; border-radius: 9px; flex: none;
  background: linear-gradient(150deg, var(--brand-500), var(--brand-700));
  display: grid; place-items: center; color: #fff;
}
.brand-mark svg { width: 16px; height: 16px; }
.brand em { font-style: normal; color: var(--primary); }

.nav { display: flex; align-items: center; gap: var(--s1); margin-left: var(--s8); }
.nav a, .nav button.navlink {
  display: inline-flex; align-items: center; gap: var(--s1);
  padding: var(--s2) var(--s3); border-radius: var(--r-sm);
  font-family: inherit; font-size: var(--t-base); font-weight: 520;
  color: var(--text-2); background: none; border: 0; cursor: pointer;
  transition: color var(--fast) var(--ease), background var(--fast) var(--ease);
}
.nav a:hover, .nav button.navlink:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.nav a[aria-current="page"] { color: var(--text); font-weight: 600; }
.nav .caret { width: 13px; height: 13px; opacity: .6; transition: transform var(--med) var(--ease); }
.nav-item { position: relative; }
.nav-item.open .caret { transform: rotate(180deg); }

.header-actions { margin-left: auto; display: flex; align-items: center; gap: var(--s2); }

.icon-btn {
  width: 36px; height: 36px; border-radius: var(--r-sm);
  border: 1px solid var(--border); background: var(--surface); color: var(--text-2);
  cursor: pointer; display: grid; place-items: center; flex: none;
  transition: color var(--fast) var(--ease), background var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.icon-btn:hover { background: var(--surface-2); color: var(--text); border-color: var(--border-firm); }
.icon-btn svg { width: 17px; height: 17px; }

.theme-toggle .moon { display: none; }
:root[data-theme="dark"] .theme-toggle .sun { display: none; }
:root[data-theme="dark"] .theme-toggle .moon { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .sun { display: none; }
  :root:not([data-theme="light"]) .theme-toggle .moon { display: block; }
}

/* mega menu */
.mega {
  position: absolute; top: calc(100% + var(--s3)); left: calc(-1 * var(--s3));
  width: min(94vw, 720px);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--sh-3);
  padding: var(--s6); display: none;
  grid-template-columns: repeat(3, 1fr); gap: var(--s1) var(--s6);
}
.nav-item.open .mega { display: grid; animation: rise var(--med) var(--ease); }
@keyframes rise { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.mega h4 {
  grid-column: 1 / -1; margin: var(--s4) 0 var(--s1);
  font-size: var(--t-xs); font-weight: 680; letter-spacing: .12em;
  text-transform: uppercase; color: var(--faint);
}
.mega h4:first-child { margin-top: 0; }
.mega a {
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s2) var(--s3); border-radius: var(--r-sm);
  font-size: var(--t-base); font-weight: 500; color: var(--text-2);
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.mega a:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.mega a svg { width: 16px; height: 16px; flex: none; opacity: .75; }
.mega-foot {
  grid-column: 1 / -1; margin-top: var(--s5); padding-top: var(--s4);
  border-top: 1px solid var(--border-soft);
  display: flex; justify-content: space-between; align-items: center;
  font-size: var(--t-base); color: var(--muted);
}

.menu-btn { display: none; }
.mobile-nav {
  display: none; position: fixed; inset: var(--header-h) 0 0; z-index: 55;
  background: var(--bg); overflow-y: auto; padding: var(--s6) 0 var(--s12);
}
.mobile-nav.open { display: block; }
.mobile-nav a {
  display: block; padding: var(--s4) 0; border-bottom: 1px solid var(--border-soft);
  color: var(--text); font-weight: 520; font-size: var(--t-md);
}
.mobile-nav a:hover { text-decoration: none; color: var(--primary); }
.mobile-nav h4 {
  margin: var(--s7) 0 var(--s1);
  font-size: var(--t-xs); font-weight: 680; letter-spacing: .12em;
  text-transform: uppercase; color: var(--faint);
}

@media (max-width: 940px) {
  .nav { display: none; }
  .menu-btn { display: grid; }
}

/* --------------------------------------------------------------------------
   5. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  padding: 10px var(--s5); border-radius: var(--r-sm); border: 1px solid transparent;
  font: inherit; font-size: var(--t-base); font-weight: 580; line-height: 1.4;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease),
              color var(--fast) var(--ease), transform var(--fast) var(--ease),
              box-shadow var(--fast) var(--ease);
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn svg { width: 16px; height: 16px; flex: none; }

.btn-primary { background: var(--primary); color: var(--on-primary); }
.btn-primary:hover { background: var(--primary-hover); box-shadow: var(--sh-2); }

.btn-ghost { background: var(--surface); color: var(--text); border-color: var(--border-firm); }
.btn-ghost:hover { background: var(--surface-2); border-color: var(--faint); }

.btn-quiet { background: transparent; color: var(--muted); }
.btn-quiet:hover { background: var(--surface-2); color: var(--text); }

.btn-success { background: var(--success); color: #fff; }
.btn-success:hover { filter: brightness(1.07); box-shadow: var(--sh-2); }

.btn-danger-quiet { background: transparent; color: var(--danger); border-color: color-mix(in srgb, var(--danger) 32%, transparent); }
.btn-danger-quiet:hover { background: var(--danger-tint); }

.btn-lg { padding: 14px var(--s7); font-size: var(--t-md); border-radius: var(--r-md); }
.btn-sm { padding: 7px var(--s3); font-size: var(--t-sm); border-radius: var(--r-xs); }
.btn-block { width: 100%; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .45; pointer-events: none; }

/* --------------------------------------------------------------------------
   6. Hero

   Two columns on desktop: the promise on the left, the action on the right.
   A centred stack of headline + panel + links reads as either cramped or
   cavernous depending on how hard you squeeze it; side by side it is neither,
   and it halves the height without taking away any breathing room.
   -------------------------------------------------------------------------- */
.hero { position: relative; padding: var(--s9) 0 var(--s8); }
.hero::before {
  content: ""; position: absolute; inset: -200px 0 auto; height: 560px; z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(720px 340px at 22% 12%, color-mix(in srgb, var(--primary) 12%, transparent), transparent 72%),
    radial-gradient(520px 300px at 86% 0%, color-mix(in srgb, var(--cat-convert) 9%, transparent), transparent 72%);
}
.hero-grid { display: grid; gap: var(--s6); align-items: center; }
/* The shortcut pills follow the drop panel in the markup so that reading and
   tab order match the stacked layout people actually get on a phone. On a
   wide screen they belong back under the copy, which is a placement job, not
   a markup one. */
@media (min-width: 920px) {
  .hero-grid {
    grid-template-columns: 1.02fr 0.98fr;
    grid-template-areas: "copy action" "links action";
    column-gap: var(--s11);
    row-gap: var(--s7);
  }
  .hero-grid > .hero-copy { grid-area: copy; }
  .hero-grid > .hero-action { grid-area: action; }
  .hero-grid > .quick-links { grid-area: links; align-self: start; }
}

.hero h1 {
  /* The <br> already sets the break, so let the browser leave it alone —
     text-wrap:balance re-flows it into an orphaned last word. Sized so each
     of the two sentences fits its line at the column width. */
  font-size: clamp(2rem, 1.15rem + 2.1vw, 2.625rem);
  line-height: 1.12;
  margin: 0 0 var(--s5);
  text-wrap: normal;
}
.hero h1 .grad {
  background: linear-gradient(96deg, var(--brand-500) 10%, var(--cat-convert) 92%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero p.lead {
  font-size: var(--t-lg); color: var(--muted); line-height: var(--lh-snug);
  max-width: 42ch; margin: 0;
}

.pill {
  display: inline-flex; align-items: center; gap: var(--s2);
  margin-bottom: var(--s5); padding: var(--s1) var(--s4) var(--s1) var(--s2);
  border-radius: var(--r-full);
  background: var(--surface); border: 1px solid var(--border);
  font-size: var(--t-sm); font-weight: 560; color: var(--text-2); box-shadow: var(--sh-1);
}
.pill b { color: var(--success); display: inline-flex; }
.pill svg { width: 14px; height: 14px; }

/* the drop panel — the primary action on the site */
.herodrop {
  position: relative; display: flex; flex-direction: column; align-items: stretch;
  gap: var(--s5); padding: var(--s6) var(--s7); cursor: pointer;
  background: var(--surface);
  border: 1.5px dashed var(--border-firm); border-radius: var(--r-xl);
  box-shadow: var(--sh-1);
  transition: border-color var(--med) var(--ease), background var(--med) var(--ease),
              box-shadow var(--med) var(--ease), transform var(--med) var(--ease);
}
.herodrop:hover, .herodrop.over {
  border-color: var(--primary); background: var(--primary-tint);
  box-shadow: var(--sh-2); transform: translateY(-2px);
}
.herodrop .hd-ic {
  width: 48px; height: 48px; border-radius: var(--r-md); flex: none;
  display: grid; place-items: center;
  background: var(--primary-tint); color: var(--primary);
  border: 1px solid var(--primary-line);
  transition: background var(--med) var(--ease);
}
.herodrop:hover .hd-ic { background: var(--surface); }
.herodrop .hd-ic svg { width: 22px; height: 22px; }
.herodrop .hd-text { display: flex; flex-direction: column; gap: var(--s1); min-width: 0; }
.herodrop .hd-text b { font-size: var(--t-lg); font-weight: 620; letter-spacing: -.018em; }
.herodrop .hd-text small { color: var(--muted); font-size: var(--t-base); line-height: var(--lh-snug); }
.herodrop .hd-cta { pointer-events: none; width: 100%; }

.hd-safe {
  display: inline-flex; align-items: center; gap: var(--s2); margin-top: var(--s4);
  font-size: var(--t-base); font-weight: 520; color: var(--muted);
}
.hd-safe svg { width: 15px; height: 15px; color: var(--success); flex: none; }

/* quick links: instant access without a wall of cards */
.quick-links { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); }
.quick-links .ql-label { font-size: var(--t-base); color: var(--faint); margin-right: var(--s1); }
.quick-links a {
  padding: var(--s2) var(--s4); border-radius: var(--r-full);
  font-size: var(--t-base); font-weight: 540; color: var(--text-2);
  background: var(--surface); border: 1px solid var(--border);
  transition: color var(--fast) var(--ease), border-color var(--fast) var(--ease), background var(--fast) var(--ease);
}
.quick-links a:hover {
  text-decoration: none; color: var(--primary);
  border-color: var(--primary-line); background: var(--primary-tint);
}

@media (max-width: 919px) {
  .hero { padding: var(--s8) 0 var(--s8); }
  .hero h1 { max-width: 18ch; }

  /* Stacked, the pills used to sit between the pitch and the drop panel and
     pushed the primary action off the bottom of a 667px phone. They are a
     convenience for people who already know which tool they want; the drop
     panel is what everyone else came for, so it leads. */
  .hero-grid { gap: var(--s6); }
}
@media (max-width: 380px) {
  /* 320px-wide phones are also the shortest ones. Scale the hero's rhythm
     with the type rather than leaving desktop spacing on a 568px screen. */
  .hero h1 { font-size: 1.75rem; }
  .hero { padding: var(--s5) 0 var(--s6); }
  .hero-grid { gap: var(--s5); }
  .hd-safe { margin-top: var(--s3); }
}
@media (max-width: 620px) {
  .hero { padding: var(--s7) 0 var(--s7); }
  .herodrop { padding: var(--s5); gap: var(--s4); }
  .quick-links .ql-label { display: none; }
}

/* full-window drop veil */
.dropveil {
  position: fixed; inset: 0; z-index: 120; display: grid; place-items: center;
  background: color-mix(in srgb, var(--bg) 74%, transparent);
  backdrop-filter: blur(4px);
  opacity: 0; pointer-events: none; transition: opacity var(--fast) var(--ease);
}
.dropveil.on { opacity: 1; }
.dropveil-card {
  display: flex; flex-direction: column; align-items: center; gap: var(--s2);
  padding: var(--s9) var(--s11); border-radius: var(--r-xl);
  background: var(--surface); border: 2px dashed var(--primary);
  box-shadow: var(--sh-3);
}
.dropveil-card svg { width: 36px; height: 36px; color: var(--primary); }
.dropveil-card strong { font-size: var(--t-xl); letter-spacing: -.02em; }
.dropveil-card span { color: var(--muted); font-size: var(--t-base); }

/* --------------------------------------------------------------------------
   7. Tool grid
   -------------------------------------------------------------------------- */
.tool-grid { display: grid; gap: var(--s4); grid-template-columns: repeat(auto-fill, minmax(246px, 1fr)); }

.tool-card {
  display: block; position: relative; padding: var(--s6);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  color: var(--text);
  transition: border-color var(--med) var(--ease), box-shadow var(--med) var(--ease),
              transform var(--med) var(--ease);
}
.tool-card:hover {
  text-decoration: none; transform: translateY(-3px);
  border-color: var(--primary-line); box-shadow: var(--sh-2);
}
.tool-card .ic {
  width: 40px; height: 40px; border-radius: var(--r-sm);
  display: grid; place-items: center; margin-bottom: var(--s5);
  background: color-mix(in srgb, currentColor var(--cat-tint), transparent);
}
.tool-card .ic svg { width: 20px; height: 20px; }
.tool-card h3 {
  font-size: var(--t-base); font-weight: 620; letter-spacing: -.015em;
  margin: 0 0 var(--s2); color: var(--text);
}
.tool-card p {
  font-size: var(--t-sm); color: var(--muted); margin: 0; line-height: 1.55;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.tool-card .tag {
  position: absolute; top: var(--s5); right: var(--s5);
  font-size: var(--t-xs); font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  padding: 2px var(--s2); border-radius: var(--r-xs);
  background: var(--warn-tint); color: var(--warn);
}

/* Category colour lives on the icon glyph only — a quiet signal, not a block. */
.cat-organize .ic { color: var(--cat-organize); }
.cat-optimize .ic { color: var(--cat-optimize); }
.cat-convert  .ic { color: var(--cat-convert); }
.cat-edit     .ic { color: var(--cat-edit); }
.cat-security .ic { color: var(--cat-security); }

.group-title {
  display: flex; align-items: baseline; gap: var(--s3);
  margin: var(--s10) 0 var(--s5);
  font-size: var(--t-xs); font-weight: 680; letter-spacing: .13em;
  text-transform: uppercase; color: var(--faint);
}
.group-title::after { content: ""; flex: 1; height: 1px; background: var(--border-soft); }
.tools-section { padding-bottom: var(--s6); }
.tools-section .group-title:first-child { margin-top: var(--s2); }

.empty-state {
  padding: var(--s11) var(--s5); text-align: center; color: var(--muted);
  border: 1px dashed var(--border); border-radius: var(--r-lg);
}
.empty-state strong { display: block; margin-bottom: var(--s2); color: var(--text); font-size: var(--t-lg); }

/* --------------------------------------------------------------------------
   8. Chips + search
   -------------------------------------------------------------------------- */
.chips { display: flex; flex-wrap: wrap; gap: var(--s2); }
.chip {
  padding: var(--s2) var(--s4); border-radius: var(--r-full);
  border: 1px solid var(--border); background: var(--surface); color: var(--text-2);
  font-family: inherit; font-size: var(--t-base); font-weight: 540;
  cursor: pointer; white-space: nowrap; flex: none;
  transition: color var(--fast) var(--ease), background var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.chip:hover { color: var(--text); border-color: var(--border-firm); }
.chip[aria-pressed="true"] { background: var(--text); border-color: var(--text); color: var(--bg); }

.toolbar-row {
  display: flex; align-items: center; gap: var(--s5); flex-wrap: wrap;
  padding-bottom: var(--s2); margin-bottom: var(--s2);
}
/* min-width:0 lets the chip strip shrink and scroll instead of forcing the
   whole page into a horizontal scroll on narrow screens. */
.toolbar-row .chips { flex: 1; min-width: 0; }

.inline-search { position: relative; flex: none; width: 250px; }
.inline-search svg {
  position: absolute; left: var(--s4); top: 50%; transform: translateY(-50%);
  width: 15px; height: 15px; color: var(--faint); pointer-events: none;
}
.inline-search input {
  width: 100%; padding: 9px var(--s8) 9px var(--s9);
  font: inherit; font-size: var(--t-base); color: var(--text);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-full);
  transition: border-color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.inline-search input::placeholder { color: var(--faint); }
.inline-search input:focus { outline: none; border-color: var(--primary); box-shadow: var(--ring); }
.inline-search kbd {
  position: absolute; right: var(--s3); top: 50%; transform: translateY(-50%);
  font-family: var(--mono); font-size: var(--t-xs); color: var(--faint);
  border: 1px solid var(--border); border-radius: var(--r-xs);
  padding: 1px 6px; line-height: 1.5; pointer-events: none;
}
.inline-search input:focus + kbd { display: none; }

.hero-search { max-width: 520px; margin: 0 auto; position: relative; }
.hero-search svg { position: absolute; left: var(--s5); top: 50%; transform: translateY(-50%); width: 18px; height: 18px; color: var(--faint); }
.hero-search input {
  width: 100%; padding: 13px var(--s5) 13px var(--s10); font: inherit; color: var(--text);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md);
  box-shadow: var(--sh-1);
}
.hero-search input:focus { outline: none; border-color: var(--primary); box-shadow: var(--ring); }

/* The tools page stacks the filter field above the category chips, rather than
   sitting them side by side the way the home page toolbar does. The field was
   left-aligned with an inline `margin: 6px 0 0`, which also zeroed the space
   under it - so the input and the chip row met with no gap at all and read as
   two boxes collided into one. */
.tools-toolbar { padding-bottom: var(--s4); }
.tools-toolbar .hero-search { margin: 0; }
.tools-toolbar .chips { margin-top: var(--s5); }

@media (max-width: 760px) {
  .toolbar-row { flex-direction: column-reverse; align-items: stretch; gap: var(--s4); }
  .inline-search { width: 100%; }
  .inline-search kbd { display: none; }
  .chips {
    flex-wrap: nowrap; overflow-x: auto; width: 100%; max-width: 100%; min-width: 0;
    padding-bottom: var(--s1); scrollbar-width: none;
    -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity;
  }
  .chips::-webkit-scrollbar { display: none; }
  .chip { scroll-snap-align: start; }
}

/* --------------------------------------------------------------------------
   9. "What can I do with this file"
   -------------------------------------------------------------------------- */
.matchpanel {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-xl); padding: var(--s7);
  margin-bottom: var(--s8); box-shadow: var(--sh-2);
  animation: rise var(--med) var(--ease);
}
.mp-head { display: flex; align-items: flex-start; gap: var(--s4); margin-bottom: var(--s6); }
.mp-head > div { flex: 1; min-width: 0; }
.mp-head h2 { font-size: var(--t-xl); margin: 0; }
.mp-head p { margin: var(--s2) 0 0; color: var(--muted); font-size: var(--t-base); }
.mp-file {
  display: inline-flex; align-items: center; gap: var(--s2); margin-bottom: var(--s2);
  padding: var(--s1) var(--s3); border-radius: var(--r-full);
  background: var(--success-tint); color: var(--success);
  font-size: var(--t-sm); font-weight: 600; max-width: 100%;
}
.mp-file svg { width: 14px; height: 14px; flex: none; }
.mp-file > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.mp-grid { display: grid; gap: var(--s3); grid-template-columns: repeat(auto-fill, minmax(208px, 1fr)); }
.mp-tool {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--s1);
  padding: var(--s4) var(--s5); border-radius: var(--r-md); cursor: pointer;
  background: var(--surface); border: 1px solid var(--border);
  font: inherit; text-align: left; color: var(--text);
  transition: transform var(--med) var(--ease), border-color var(--med) var(--ease), box-shadow var(--med) var(--ease);
}
.mp-tool:hover, .mp-tool:focus-visible {
  transform: translateY(-2px); border-color: var(--primary-line); box-shadow: var(--sh-2);
}
.mp-tool .ic {
  width: 32px; height: 32px; border-radius: var(--r-xs); display: grid; place-items: center;
  margin-bottom: var(--s2); background: color-mix(in srgb, currentColor var(--cat-tint), transparent);
}
.mp-tool .ic svg { width: 16px; height: 16px; }
.mp-tool .mp-name { font-weight: 620; font-size: var(--t-base); letter-spacing: -.012em; }
.mp-tool .mp-blurb {
  font-size: var(--t-sm); color: var(--muted); line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.mp-tool.busy { opacity: .5; pointer-events: none; }

.mp-more {
  display: inline-flex; align-items: center; gap: var(--s2); margin-top: var(--s5);
  padding: var(--s2) var(--s5); border-radius: var(--r-full); cursor: pointer;
  background: transparent; border: 1px solid var(--border);
  font: inherit; font-size: var(--t-base); font-weight: 540; color: var(--text-2);
  transition: color var(--fast) var(--ease), border-color var(--fast) var(--ease), background var(--fast) var(--ease);
}
.mp-more:hover { background: var(--surface-2); color: var(--text); border-color: var(--border-firm); }
.mp-more svg { width: 15px; height: 15px; }
#mp-rest { margin-top: var(--s3); }

/* --------------------------------------------------------------------------
   10. Features, steps, band, FAQ
   -------------------------------------------------------------------------- */
.features { display: grid; gap: var(--s5); grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
.feature { padding: var(--s7); background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); }
.feature .ic {
  width: 40px; height: 40px; border-radius: var(--r-sm); display: grid; place-items: center;
  background: var(--primary-tint); color: var(--primary); margin-bottom: var(--s5);
  border: 1px solid var(--primary-line);
}
.feature .ic svg { width: 19px; height: 19px; }
.feature h3 { font-size: var(--t-md); margin-bottom: var(--s2); }
.feature p { color: var(--muted); font-size: var(--t-base); margin: 0; line-height: 1.6; }

.steps {
  display: grid; gap: var(--s7);
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  counter-reset: s;
}
.steps-block { margin-top: var(--s9); }
.steps-label {
  font-size: var(--t-xs); font-weight: 680; letter-spacing: .12em; text-transform: uppercase;
  color: var(--faint); margin: 0 0 var(--s5);
}
.step { position: relative; }

/* The number was a bare figure sitting above a heading, which read as loose
   text rather than a sequence. A badge on a rail says "step 2 of 3" at a
   glance and costs no extra markup. */
.step::before {
  counter-increment: s; content: counter(s, decimal-leading-zero);
  position: relative; z-index: 1;
  display: grid; place-items: center;
  width: 40px; height: 40px; margin-bottom: var(--s5);
  border-radius: var(--r-full);
  background: var(--primary-tint); border: 1px solid var(--primary-line);
  color: var(--primary);
  font-size: var(--t-sm); font-weight: 700; letter-spacing: .02em;
  font-variant-numeric: tabular-nums;
}
.step h3 { font-size: var(--t-md); margin-bottom: var(--s2); }
.step p { color: var(--muted); font-size: var(--t-base); margin: 0; line-height: 1.6; }

/* One row only, so the rail between badges always has somewhere to land. */
@media (min-width: 860px) {
  .steps { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 1fr; }
  /* Four steps in a single row need more width than three before the columns
     get too narrow to read; below that they wrap, and a rail pointing into a
     line break is worse than no rail. */
  @media (max-width: 1039px) {
    .steps:has(.step:nth-child(4)) {
      grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); grid-auto-flow: row;
    }
    .steps:has(.step:nth-child(4)) .step::after { display: none; }
  }
  .step:not(:last-child)::after {
    content: ""; position: absolute; top: 20px; left: 52px;
    right: calc(var(--s7) * -1); height: 1px;
    background: linear-gradient(90deg, var(--primary-line), var(--border) 55%);
  }
}

/* Stacked, the same sequence reads better as a timeline: badge in a gutter,
   the rail running down between one step and the next. */
@media (max-width: 519px) {
  /* Forced to one column so the rail below always joins one step to the next.
     At two columns the sequence runs across, not down, and a vertical rail
     would point at the wrong step. */
  .steps { grid-template-columns: 1fr; gap: var(--s6); }
  .step {
    display: grid; grid-template-columns: 40px minmax(0, 1fr);
    column-gap: var(--s4); align-items: start;
  }
  .step::before { grid-column: 1; grid-row: 1 / span 2; margin-bottom: 0; }
  .step h3 { grid-column: 2; grid-row: 1; margin-bottom: var(--s1); align-self: center; min-height: 40px; display: flex; align-items: center; }
  .step p { grid-column: 2; grid-row: 2; }
  .step:not(:last-child)::after {
    content: ""; position: absolute; left: 19px; top: 44px;
    bottom: calc(var(--s6) * -1); width: 1px; background: var(--border);
  }
}

.band {
  position: relative; overflow: hidden; text-align: center;
  padding: var(--s12) var(--s8); border-radius: var(--r-xl);
  background: linear-gradient(140deg, var(--brand-700), var(--brand-500) 55%, #6f4ff7);
  color: #fff;
}
.band::after {
  content: ""; position: absolute; inset: auto -10% -60% 40%; height: 340px;
  background: radial-gradient(closest-side, rgba(255,255,255,.16), transparent);
  pointer-events: none;
}
.band h2 { color: #fff; margin-bottom: var(--s4); }
.band p { color: rgba(255,255,255,.82); max-width: 48ch; margin: 0 auto var(--s7); font-size: var(--t-lg); line-height: var(--lh-snug); }
.band .btn-ghost { position: relative; background: #fff; color: var(--brand-700); border-color: #fff; }
.band .btn-ghost:hover { background: rgba(255,255,255,.9); border-color: rgba(255,255,255,.9); }

.faq { border-top: 1px solid var(--border); }
.faq details { border-bottom: 1px solid var(--border); }
.faq summary {
  padding: var(--s6) var(--s9) var(--s6) 0; cursor: pointer; list-style: none;
  font-size: var(--t-md); font-weight: 580; position: relative;
  transition: color var(--fast) var(--ease);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; position: absolute; right: var(--s3); top: 50%;
  width: 9px; height: 9px; margin-top: -6px;
  border-right: 1.8px solid var(--faint); border-bottom: 1.8px solid var(--faint);
  transform: rotate(45deg);
  transition: transform var(--med) var(--ease), border-color var(--fast) var(--ease);
}
.faq summary:hover { color: var(--primary); }
.faq summary:hover::after { border-color: var(--primary); }
.faq details[open] summary::after { transform: rotate(225deg); margin-top: -2px; }
.faq .body { padding: 0 var(--s9) var(--s6) 0; color: var(--text-2); font-size: var(--t-base); line-height: var(--lh-body); }
.faq .body p:last-child { margin: 0; }

/* --------------------------------------------------------------------------
   11. Tool page
   -------------------------------------------------------------------------- */
.crumbs { font-size: var(--t-sm); color: var(--faint); padding-top: var(--s6); }
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--primary); }
.crumbs span { margin: 0 var(--s2); opacity: .5; }

.tool-hero { padding: var(--s8) 0 var(--s2); text-align: center; }
.tool-hero .ic {
  width: 56px; height: 56px; border-radius: var(--r-md); display: grid; place-items: center;
  margin: 0 auto var(--s5);
  background: color-mix(in srgb, currentColor var(--cat-tint), transparent);
  border: 1px solid color-mix(in srgb, currentColor 20%, transparent);
}
.tool-hero .ic svg { width: 26px; height: 26px; }
.tool-hero h1 { font-size: clamp(1.75rem, 1.3rem + 1.9vw, 2.5rem); margin-bottom: var(--s4); }
.tool-hero p { color: var(--muted); font-size: var(--t-lg); max-width: 52ch; margin: 0 auto; line-height: var(--lh-snug); }

.workspace { max-width: 820px; margin: var(--s8) auto 0; }

/* Above the fold on a tool page.
   Stacked, the crumbs + centred hero push the drop zone to ~364px, so on a
   1366x768 laptop (viewport ~657px) the box is clipped by 100px and the one
   thing the visitor came to do is half off-screen. Side by side, hero and
   drop zone both land in the first screen — the same trade the home page
   hero makes, for the same reason. Idle only: once a file is loaded the
   working-mode rules below take over and the work gets the full width. */
.tool-top-grid { display: grid; gap: var(--s6); align-items: start; }
.tool-top-grid > .workspace { margin-top: 0; }
/* The grid gap owns the space between the hero row and the work; the
   workspace's own margin would otherwise stack on top of it. */
body[data-working] .tool-top-grid { gap: var(--s6); }
body[data-working] .tool-top-grid > .workspace { margin-top: 0; }

@media (min-width: 920px) {
  body:not([data-working]) .tool-top-grid {
    grid-template-columns: 1fr 1.06fr;
    gap: var(--s10);
    align-items: center;
    padding-block: var(--s7) var(--s6);
  }
  body:not([data-working]) .tool-top-grid > .tool-hero { padding: 0; text-align: left; }
  body:not([data-working]) .tool-top-grid > .tool-hero .ic { margin-inline: 0; }
  body:not([data-working]) .tool-top-grid > .tool-hero p { margin-inline: 0; }
  body:not([data-working]) .tool-top-grid > .workspace { margin: 0; max-width: none; }
}

@media (max-width: 919px) {
  body:not([data-working]) .tool-top-grid > .tool-hero {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-template-areas: "ic title" "desc desc";
    align-items: center;
    gap: var(--s3) var(--s4);
    text-align: left;
    padding: var(--s6) 0 0;
  }
  body:not([data-working]) .tool-top-grid > .tool-hero .ic {
    grid-area: ic; width: 44px; height: 44px; margin: 0; border-radius: var(--r-sm);
  }
  body:not([data-working]) .tool-top-grid > .tool-hero .ic svg { width: 21px; height: 21px; }
  body:not([data-working]) .tool-top-grid > .tool-hero h1 { grid-area: title; margin: 0; }
  body:not([data-working]) .tool-top-grid > .tool-hero p { grid-area: desc; margin: 0; max-width: none; }
}
/* A grid of page thumbnails is the one control that genuinely wants the whole
   screen — six per row on a wide monitor is a scroll nobody needs. */
.workspace:has(.pages) { max-width: 1280px; }

/* Working mode. The title, the icon and the one-line pitch are what sell the
   tool to someone who just arrived; the moment a file is loaded they are
   spending the fold on something the visitor already decided. Collapse them
   to a single compact row and give the space back to the work. */
body[data-working] .tool-hero { padding: var(--s6) 0 0; }
body[data-working] .tool-hero { display: flex; align-items: center; gap: var(--s4); text-align: left; }
body[data-working] .tool-hero .ic { width: 38px; height: 38px; margin: 0; flex: none; border-radius: var(--r-sm); }
body[data-working] .tool-hero .ic svg { width: 19px; height: 19px; }
body[data-working] .tool-hero h1 { font-size: var(--t-xl); margin: 0; }
body[data-working] .tool-hero p { display: none; }
body[data-working] .workspace { margin-top: var(--s6); }
@media (max-width: 760px) { body[data-working] .crumbs { display: none; } }
/* Wide screens: controls on the left, live preview parked on the right. */
.ws { display: grid; gap: var(--s6); align-items: start; }
.ws[data-split="true"] { max-width: 1280px; margin-inline: auto; }
@media (min-width: 1080px) {
  .workspace:has(.ws[data-split="true"]) { max-width: 1280px; }
  .ws[data-split="true"] { grid-template-columns: minmax(0, 1fr) minmax(0, 1.02fr); gap: var(--s7); }
  .ws[data-split="true"] .ws-side { position: sticky; top: calc(var(--header-h) + var(--s6)); }
  /* The panel is pinned, so it has to fit the window: label, stage and page
     nav together, with the header and its own chrome subtracted. */
  .ws[data-split="true"] .ws-side .pv-stage canvas {
    max-height: min(70vh, calc(100vh - var(--header-h) - 240px));
  }
}

/* Narrow screens get the same deal, stacked. The preview leads and stays
   pinned under the header, so a slider and the thing it moves are on screen
   at the same time — the one place every other PDF site makes you guess. */
@media (max-width: 1079px) {
  .ws[data-split="true"] { display: flex; flex-direction: column; align-items: stretch; }
  .ws[data-split="true"] .ws-side:has(.preview-panel) {
    order: -1; position: sticky; top: var(--header-h); z-index: 6;
    padding: var(--s2) 0; background: var(--bg);
  }
  /* A pinned panel spends viewport the controls below it also need, so the
     preview runs to about a quarter of the screen and no further. */
  .ws[data-split="true"] .ws-side .preview-panel { padding: var(--s4); }
  .ws[data-split="true"] .ws-side .preview-panel > h3 { margin-bottom: var(--s3); }
  .ws[data-split="true"] .ws-side .pv-stage { min-height: 0; padding: var(--s3); }
  .ws[data-split="true"] .ws-side .pv-stage canvas { max-height: 24vh; width: auto; }
  .ws[data-split="true"] .ws-side .pv-nav { margin-top: var(--s3); }
}
.ws-main > *:first-child, .ws-side > *:first-child { margin-top: 0; }

.drop {
  border: 1.5px dashed var(--border-firm); border-radius: var(--r-xl);
  background: var(--surface); padding: clamp(var(--s6), 6.5vh, var(--s12)) var(--s7);
  text-align: center; cursor: pointer;
  transition: border-color var(--med) var(--ease), background var(--med) var(--ease);
}
.drop:hover, .drop.over { border-color: var(--primary); background: var(--primary-tint); }
.drop .ic {
  width: 52px; height: 52px; margin: 0 auto var(--s5); border-radius: var(--r-md);
  display: grid; place-items: center;
  background: var(--primary-tint); color: var(--primary); border: 1px solid var(--primary-line);
}
.drop .ic svg { width: 24px; height: 24px; }
.drop h3 { font-size: var(--t-lg); margin-bottom: var(--s2); }
.drop p { color: var(--muted); font-size: var(--t-base); margin: 0; }
.drop .btn { margin-top: var(--s6); pointer-events: none; }

.panel {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: var(--s6); margin-top: var(--s5);
}
.panel > h3 {
  font-size: var(--t-xs); font-weight: 680; letter-spacing: .12em; text-transform: uppercase;
  color: var(--faint); margin-bottom: var(--s5);
}

.filelist { display: flex; flex-direction: column; gap: var(--s2); }
.fileitem {
  display: flex; align-items: center; gap: var(--s4); padding: var(--s3);
  background: var(--surface-2); border: 1px solid var(--border-soft); border-radius: var(--r-md);
}
.fileitem.dragging { opacity: .4; }
.fileitem .grip { color: var(--faint); cursor: grab; display: grid; place-items: center; }
.fileitem .grip svg { width: 15px; height: 15px; }
.fileitem .thumb {
  width: 38px; height: 50px; flex: none; border-radius: var(--r-xs); overflow: hidden;
  background: var(--surface-3); border: 1px solid var(--border); display: grid; place-items: center;
}
.fileitem .thumb:not(.ready) { opacity: .4; }
.fileitem .thumb canvas { width: 100%; height: 100%; object-fit: cover; }
.fileitem .fi { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 1px; }
.fileitem .fn { font-weight: 580; font-size: var(--t-base); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fileitem .fs { font-size: var(--t-sm); color: var(--muted); }
.fileitem .x {
  border: 0; background: none; color: var(--faint); cursor: pointer;
  padding: var(--s1); border-radius: var(--r-xs); display: grid; place-items: center;
  transition: color var(--fast) var(--ease), background var(--fast) var(--ease);
}
.fileitem .x:hover { color: var(--danger); background: var(--danger-tint); }
.fileitem .x svg { width: 15px; height: 15px; }

/* options */
.opts { display: grid; gap: var(--s5); grid-template-columns: repeat(auto-fit, minmax(196px, 1fr)); }
.opt { display: flex; flex-direction: column; gap: var(--s2); }
.opt.full { grid-column: 1 / -1; }
.opt label { font-size: var(--t-sm); font-weight: 600; color: var(--text-2); }
.opt .hint { font-size: var(--t-xs); color: var(--muted); line-height: 1.5; }
.opt input[type="text"], .opt input[type="number"], .opt input[type="email"],
.opt select, .opt textarea, .field {
  width: 100%; padding: 9px var(--s3); font: inherit; font-size: var(--t-base); color: var(--text);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-sm);
  transition: border-color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.opt textarea { min-height: 92px; resize: vertical; font-family: var(--mono); font-size: var(--t-sm); }
.opt input:focus, .opt select:focus, .opt textarea:focus, .field:focus {
  outline: none; border-color: var(--primary); box-shadow: var(--ring);
}
.opt input[type="color"] {
  width: 100%; height: 38px; padding: 3px; cursor: pointer;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-sm);
}
.opt input[type="range"] { width: 100%; accent-color: var(--primary); margin: var(--s1) 0; }
.opt .rangeval { font-variant-numeric: tabular-nums; font-weight: 660; color: var(--primary); }
.opt.check { flex-direction: row; align-items: center; gap: var(--s3); }
.opt.check input { width: 16px; height: 16px; accent-color: var(--primary); flex: none; }
.opt.check label { font-size: var(--t-base); font-weight: 500; color: var(--text); }

.seg { display: flex; gap: var(--s1); padding: var(--s1); background: var(--surface-2); border-radius: var(--r-sm); }
.seg button {
  flex: 1 1 auto; padding: 7px var(--s3); border-radius: var(--r-xs);
  font: inherit; font-size: var(--t-sm); font-weight: 560; cursor: pointer;
  background: transparent; border: 1px solid transparent; color: var(--muted);
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.seg button:hover { color: var(--text); }
.seg button[aria-pressed="true"] {
  background: var(--surface); color: var(--text); box-shadow: var(--sh-1); border-color: var(--border-soft);
}

.posgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s1); max-width: 132px; }
.posgrid button {
  aspect-ratio: 1; border-radius: var(--r-xs); border: 1px solid var(--border);
  background: var(--surface-2); cursor: pointer; display: grid; place-items: center;
  transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.posgrid button::after { content: ""; width: 6px; height: 6px; border-radius: 2px; background: var(--faint); }
.posgrid button:hover { border-color: var(--border-firm); }
.posgrid button[aria-pressed="true"] { background: var(--primary-tint); border-color: var(--primary); }
.posgrid button[aria-pressed="true"]::after { background: var(--primary); }

.actionbar { display: flex; gap: var(--s3); align-items: center; justify-content: center; margin: var(--s7) 0 var(--s2); flex-wrap: wrap; }

/* The command bar.

   A long options list used to push the one button that matters two screens
   down. It now rides the bottom of the window for as long as there is work
   to run, carrying its own status: what you are about to act on, any error,
   and the progress of the run itself. It settles into the flow at the end
   of the column, so it never sits on top of the page furniture below. */
.actionbar-live {
  position: sticky; bottom: var(--s4); z-index: 20;
  display: block; margin: var(--s7) 0 var(--s2);
  padding: var(--s4) var(--s5);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  background: color-mix(in srgb, var(--surface) 90%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  backdrop-filter: saturate(180%) blur(14px);
  box-shadow: var(--sh-2);
}
.actionbar-live .ab-row { display: flex; align-items: center; gap: var(--s3); }
.actionbar-live .ab-sum {
  margin-right: auto; min-width: 0; font-size: var(--t-sm); color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.actionbar-live .ab-sum:empty { display: none; }
.actionbar-live .progress,
.actionbar-live .alert { margin: 0 0 var(--s3); }
.actionbar-live .progress .msg { text-align: left; }
@media (max-width: 620px) {
  .actionbar-live { bottom: var(--s2); padding: var(--s3) var(--s4); }
  .actionbar-live .ab-sum { display: none; }
  .actionbar-live #go { flex: 1; }
  .actionbar-live #reset { padding-inline: var(--s4); }
}

.progress { margin-top: var(--s5); }
.progress .bar { height: 6px; border-radius: var(--r-full); background: var(--surface-3); overflow: hidden; }
.progress .bar i {
  display: block; height: 100%; width: 0; border-radius: var(--r-full);
  background: linear-gradient(90deg, var(--primary), var(--cat-convert));
  transition: width var(--med) var(--ease);
}
.progress .msg { font-size: var(--t-sm); color: var(--muted); margin-top: var(--s3); text-align: center; }

/* result */
.result {
  text-align: center; padding: var(--s9) var(--s7);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-xl);
  animation: rise var(--med) var(--ease);
}
.result .tick {
  width: 56px; height: 56px; border-radius: 50%; margin: 0 auto var(--s5);
  background: var(--success-tint); color: var(--success); display: grid; place-items: center;
}
.result .tick svg { width: 26px; height: 26px; }
.result h2 { font-size: var(--t-xl); margin-bottom: var(--s2); }
.result .meta { color: var(--muted); font-size: var(--t-base); margin-bottom: var(--s7); }
.result .meta b { color: var(--text); }
.result .again { margin-top: var(--s5); }

.alert {
  display: flex; gap: var(--s3); align-items: flex-start;
  padding: var(--s4) var(--s5); border-radius: var(--r-md);
  font-size: var(--t-base); line-height: 1.55; margin-top: var(--s5);
}
.alert svg { width: 17px; height: 17px; flex: none; margin-top: 2px; }
.alert-error { background: var(--danger-tint); color: var(--danger); border: 1px solid color-mix(in srgb, var(--danger) 24%, transparent); }
.alert-info  { background: var(--primary-tint); color: var(--primary-deep); border: 1px solid var(--primary-line); }
.alert-success { background: var(--success-tint); color: var(--success); border: 1px solid color-mix(in srgb, var(--success) 26%, transparent); }

/* Contact form honeypot. Positioned off-screen rather than display:none,
   which the bots worth catching already know to skip. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* Contact page columns. Previously an inline style on the element plus an
   inline <style> block with an !important override - which meant the page's
   layout lived in the HTML document rather than here, where the rest of the
   responsive system can see it. */
.contact-cols {
  display: grid; gap: var(--s7);
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  align-items: start;
}
@media (max-width: 820px) { .contact-cols { grid-template-columns: 1fr; } }
:root[data-theme="dark"] .alert-info { color: var(--brand-700); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .alert-info { color: var(--brand-700); } }

/* page thumbnails */
.pages {
  display: grid; gap: var(--s4); grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  max-height: min(520px, 56vh); overflow-y: auto; padding: var(--s1);
}
.pg {
  position: relative; border-radius: var(--r-sm); overflow: hidden;
  background: var(--surface-2); border: 2px solid var(--border); cursor: pointer;
  transition: border-color var(--fast) var(--ease), transform var(--fast) var(--ease);
}
.pg:hover { transform: translateY(-2px); }
.pg.sel { border-color: var(--primary); }
.pg.dead { opacity: .3; }
.pg.dragging { opacity: .35; }
.pg canvas { width: 100%; height: auto; display: block; background: #fff; transition: transform var(--med) var(--ease); }
.pg .n {
  position: absolute; bottom: 0; left: 0; right: 0; padding: 3px;
  background: linear-gradient(transparent, rgba(10,12,26,.78));
  color: #fff; font-size: var(--t-xs); text-align: center; font-weight: 620;
}
.pg .acts { position: absolute; top: var(--s1); right: var(--s1); display: flex; gap: 3px; opacity: 0; transition: opacity var(--fast) var(--ease); }
.pg:hover .acts, .pg:focus-within .acts { opacity: 1; }
.pg .acts button {
  width: 24px; height: 24px; border-radius: var(--r-xs); border: 0; cursor: pointer;
  background: rgba(10,12,26,.8); color: #fff; display: grid; place-items: center;
}
.pg .acts button:hover { background: var(--primary); }
.pg .acts svg { width: 12px; height: 12px; }

/* signature */
.sigpad {
  border: 1.5px dashed var(--border-firm); border-radius: var(--r-md);
  background: #fff; touch-action: none; cursor: crosshair; width: 100%; height: 180px;
}
.stage {
  position: relative; display: inline-block; max-width: 100%;
  border: 1px solid var(--border); border-radius: var(--r-md); overflow: hidden; background: #fff;
}
.stage canvas { display: block; }
.stage .ghost { position: absolute; pointer-events: none; border: 1px dashed var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent); }

/* live preview */
.preview-panel > h3 { display: flex; align-items: center; gap: var(--s2); }
.pv-tag {
  font-size: var(--t-xs); letter-spacing: .06em; padding: 2px var(--s2); border-radius: var(--r-xs);
  background: var(--warn-tint); color: var(--warn); font-weight: 700; text-transform: none;
}
.pv-tag:empty { display: none; }
.pv-stage {
  position: relative; display: flex; justify-content: center;
  background: var(--surface-2); border: 1px solid var(--border-soft);
  border-radius: var(--r-md); padding: var(--s5); min-height: 240px;
}
.pv-stage canvas { max-width: 100%; height: auto; background: #fff; box-shadow: var(--sh-2); border-radius: 2px; }
.pv-busy {
  position: absolute; inset: 0; display: grid; place-items: center; border-radius: var(--r-md);
  background: color-mix(in srgb, var(--surface-2) 62%, transparent);
  opacity: 0; pointer-events: none; transition: opacity var(--fast) var(--ease);
}
.pv-busy.on { opacity: 1; }
.spinner {
  width: 24px; height: 24px; border-radius: 50%;
  border: 2.5px solid color-mix(in srgb, var(--primary) 22%, transparent);
  border-top-color: var(--primary); animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.pv-nav { display: flex; align-items: center; gap: var(--s3); margin-top: var(--s4); flex-wrap: wrap; }
.pv-nav .pv-note { margin-left: auto; color: var(--faint); }
.pv-nav button[disabled] { opacity: .35; pointer-events: none; }
@media (max-width: 600px) { .pv-nav .pv-note { display: none; } }

/* chain */
.chain { margin-top: var(--s8); padding-top: var(--s7); border-top: 1px solid var(--border-soft); }
.chain-label {
  display: block; margin-bottom: var(--s4);
  font-size: var(--t-xs); font-weight: 680; letter-spacing: .13em;
  text-transform: uppercase; color: var(--faint);
}
.chain-row { display: flex; flex-wrap: wrap; gap: var(--s2); justify-content: center; }
.chain-chip {
  display: inline-flex; align-items: center; gap: var(--s2);
  padding: var(--s2) var(--s4) var(--s2) var(--s2); border-radius: var(--r-full); cursor: pointer;
  background: var(--surface); border: 1px solid var(--border);
  font: inherit; font-size: var(--t-base); font-weight: 560; color: var(--text);
  transition: transform var(--fast) var(--ease), border-color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.chain-chip:hover { transform: translateY(-2px); border-color: var(--primary-line); box-shadow: var(--sh-1); }
.chain-chip.busy { opacity: .45; pointer-events: none; }
.chain-chip .ic {
  width: 24px; height: 24px; border-radius: var(--r-xs); display: grid; place-items: center;
  background: color-mix(in srgb, currentColor var(--cat-tint), transparent);
}
.chain-chip .ic svg { width: 13px; height: 13px; }
.chain-hint { display: block; margin-top: var(--s4); font-size: var(--t-sm); color: var(--faint); }

/* --------------------------------------------------------------------------
   12. Content pages
   -------------------------------------------------------------------------- */
/* No rule under the hero: the home page hero does not have one, and the space
   plus the type hierarchy already separate the two. What the border was really
   exposing was that .wrap carries no vertical padding, so the gap under it was
   whatever the first child happened to contribute - 0px on About, where the
   heading landed flush against the line, 25px on Contact, 48px on the legal
   pages. The rule below makes that spacing deliberate and equal everywhere. */
.page-hero { padding: var(--s12) 0 var(--s8); }
.page-hero + .wrap { padding-top: var(--s9); }
.page-hero h1 { max-width: 20ch; margin-bottom: var(--s5); }
.page-hero .lead { font-size: var(--t-lg); color: var(--muted); max-width: 58ch; margin: 0; line-height: var(--lh-snug); }
.updated {
  display: inline-flex; align-items: center; gap: var(--s2);
  padding: var(--s1) var(--s4); border-radius: var(--r-full);
  background: var(--surface); border: 1px solid var(--border);
  font-size: var(--t-sm); color: var(--muted); margin-bottom: var(--s5);
}

/* long-form reading column */
.prose { max-width: var(--measure); }
.prose > h2 {
  margin-top: var(--s11); margin-bottom: var(--s4);
  font-size: var(--t-xl); scroll-margin-top: calc(var(--header-h) + var(--s6));
}
.prose > h2:first-child { margin-top: 0; }
.prose > h3 { margin-top: var(--s8); margin-bottom: var(--s3); font-size: var(--t-md); }
.prose p, .prose li { color: var(--text-2); font-size: var(--t-md); line-height: 1.75; }
.prose ul, .prose ol { margin-bottom: var(--s5); }
.prose li { margin-bottom: var(--s3); padding-left: var(--s1); }
.prose li::marker { color: var(--faint); }

.callout {
  margin: var(--s7) 0; padding: var(--s6);
  background: var(--primary-tint); border: 1px solid var(--primary-line); border-radius: var(--r-md);
}
.callout p { color: var(--text-2); }
.callout p:last-child { margin: 0; }
.callout strong { color: var(--primary-deep); }
:root[data-theme="dark"] .callout strong { color: var(--brand-700); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .callout strong { color: var(--brand-700); } }

/* legal pages: sticky contents beside the reading column */
.legal-layout { display: grid; gap: var(--s9); align-items: start; }
/* Grid items default to min-width:auto, so the two-column contents list below
   was sizing itself to its min-content (2 x ~212px) and pushing the whole
   legal page into a sideways scroll on a phone. */
.legal-layout > * { min-width: 0; }
@media (min-width: 1000px) {
  .legal-layout { grid-template-columns: 230px minmax(0, 1fr); gap: var(--s11); }
  .legal-toc { position: sticky; top: calc(var(--header-h) + var(--s7)); }
}
.legal-toc h2 {
  font-size: var(--t-xs) !important; font-weight: 680; letter-spacing: .13em;
  text-transform: uppercase; color: var(--faint); margin: 0 0 var(--s4) !important;
}
.legal-toc ol { list-style: none; padding: 0; margin: 0; }
.legal-toc li { margin: 0; }
.legal-toc a {
  display: block; padding: var(--s2) 0 var(--s2) var(--s4);
  border-left: 2px solid var(--border);
  font-size: var(--t-base); color: var(--muted); line-height: 1.45;
  transition: color var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.legal-toc a:hover { color: var(--primary); border-left-color: var(--primary); text-decoration: none; }
@media (max-width: 999px) {
  .legal-toc { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: var(--s6); }
  .legal-toc ol { columns: 2; column-gap: var(--s6); }
  .legal-toc a { border-left: 0; padding-left: 0; }
}
@media (max-width: 560px) {
  /* Two columns of section titles on a phone is two words per line. */
  .legal-toc ol { columns: 1; }
}

.toc {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: var(--s6); margin-bottom: var(--s8);
}
.toc h2 { font-size: var(--t-xs) !important; letter-spacing: .13em; text-transform: uppercase; color: var(--faint); margin: 0 0 var(--s3) !important; }
.toc ol { margin: 0; font-size: var(--t-base); }

.cards { display: grid; gap: var(--s5); grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.card { padding: var(--s7); background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); }
.card h3 { font-size: var(--t-md); margin-bottom: var(--s2); }
.card p { color: var(--muted); font-size: var(--t-base); line-height: 1.6; }
.card p:last-child { margin: 0; }
.card .ic {
  width: 38px; height: 38px; border-radius: var(--r-sm); display: grid; place-items: center;
  background: var(--primary-tint); color: var(--primary); margin-bottom: var(--s5);
  border: 1px solid var(--primary-line);
}
.card .ic svg { width: 18px; height: 18px; }

.stats { display: grid; gap: var(--s6); grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.stat b { display: block; font-size: var(--t-3xl); font-weight: 680; color: var(--primary); letter-spacing: -.035em; }
.stat span { font-size: var(--t-base); color: var(--muted); }

table.tbl { width: 100%; border-collapse: collapse; font-size: var(--t-base); }
table.tbl th, table.tbl td {
  padding: var(--s4) var(--s5); border-bottom: 1px solid var(--border-soft);
  text-align: left; vertical-align: top; line-height: 1.6;
}
table.tbl tr:last-child td { border-bottom: 0; }
table.tbl th {
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .1em;
  color: var(--faint); font-weight: 680; background: var(--surface-2);
}
table.tbl td { color: var(--text-2); }
.tbl-scroll {
  overflow-x: auto; border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--surface); margin-bottom: var(--s5);
}

/* --------------------------------------------------------------------------
   13. Footer
   -------------------------------------------------------------------------- */
.site-footer { margin-top: var(--s13); border-top: 1px solid var(--border); background: var(--surface); }
.footer-top { display: grid; gap: var(--s9); grid-template-columns: 1.6fr repeat(4, 1fr); padding: var(--s11) 0 var(--s9); }
.footer-brand p { color: var(--muted); font-size: var(--t-base); max-width: 30ch; margin: var(--s5) 0 0; line-height: 1.65; }
.footer-col h4 {
  font-size: var(--t-xs); font-weight: 680; letter-spacing: .12em;
  text-transform: uppercase; color: var(--faint); margin-bottom: var(--s4);
}
.footer-col a {
  display: block; padding: var(--s2) 0; font-size: var(--t-base); color: var(--text-2);
  transition: color var(--fast) var(--ease);
}
.footer-col a:hover { color: var(--primary); text-decoration: none; }
.footer-bottom {
  border-top: 1px solid var(--border-soft); padding: var(--s6) 0;
  display: flex; justify-content: space-between; gap: var(--s5); flex-wrap: wrap;
  font-size: var(--t-base); color: var(--muted);
}
.footer-bottom nav { display: flex; gap: var(--s6); flex-wrap: wrap; }
.footer-bottom nav a { color: var(--muted); }
.footer-bottom nav a:hover { color: var(--primary); }

@media (max-width: 900px) {
  .footer-top { grid-template-columns: 1fr 1fr; gap: var(--s7); }
  .footer-brand { grid-column: 1 / -1; }
}
@media (max-width: 520px) { .footer-top { grid-template-columns: 1fr; } }

/* --------------------------------------------------------------------------
   14. Misc
   -------------------------------------------------------------------------- */
@media (max-width: 620px) {
  .panel { padding: var(--s5); }
  .drop { padding: clamp(var(--s5), 4.2vh, var(--s9)) var(--s5); }
  .band { padding: var(--s9) var(--s6); }
  .result { padding: var(--s7) var(--s5); }
  .matchpanel { padding: var(--s5); }
}

@media print {
  .site-header, .site-footer, .actionbar, .drop, .mobile-nav, .dropveil { display: none !important; }
  body { background: #fff; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}
